<commit_before>/**
 * @file regex.cpp
 * @brief  Brief description of file.
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <ctype.h>
#include <errno.h>
#include <regex.h>

#include <angort/angort.h>
#include <angort/hash.h>

using namespace angort;

%name regex
%shared

class Regex : public GarbageCollected {
public:
    regex_t *r;
    int errorcode; //zero or error code
    Regex(const char *s,bool icase){
        r = new regex_t;
        int f = REG_EXTENDED;
        if(icase) f|= REG_ICASE;
        errorcode = regcomp(r,s,f);
    }
    virtual ~Regex(){
        regfree(r);
    }
};

class RegexType : public GCType {
public:
    RegexType(){
        add("regex","REGX");
    }
    virtual ~RegexType(){};

    Regex *get(const Value *v) const {
        if(v->t != this)
            throw RUNT(EX_TYPE,"not a regex");
        return (Regex *)(v->v.gc);
    }

    Regex *set(Value *v,const char *s,bool icase){
        v->clr();
        v->t=this;
        Regex *r = new Regex(s,icase);
        v->v.gc = r;
        incRef(v);
        return r;
    }
};

static RegexType tR;

%type regex tR Regex

void docompile(Runtime *a,const char *p0,bool icase){
    char *s = strdup(p0); // copy to avoid pushval overwrite
    Value *v = a->pushval();
    Regex *r = tR.set(v,s,icase);
    free(s);

    if(r->errorcode){
        int size = regerror(r->errorcode,r->r,NULL,0)+1;
        char *s = (char *)alloca(size);
        regerror(r->errorcode,r->r,s,1024);
        throw RUNT(EX_FAILED,"").set("regex compile error: %s",s);
    }
}

%wordargs compile s (string -- compiled regex) compile a regex
{
    docompile(a,p0,false);
}

%wordargs compileicase s (string -- compiled regex) compile a regex (case independent)
{
    docompile(a,p0,true);
}

%wordargs chk A|regex (regex -- none or string) error check
{
    Value *v = a->pushval();
    if(p0->errorcode){
        int size = regerror(p0->errorcode,p0->r,NULL,0)+1;
        char *s = Types::tString->allocate(v,size,Types::tString);
        regerror(p0->errorcode,p0->r,s,1024);
    } else {
        a->pushNone();
    }
}

%wordargs match sA|regex (str regex -- matchlist) match
{
    regmatch_t match;
    Value v;
    ArrayList<Value> *list = Types::tList->set(&v);
    int off=0;
    int flags = 0;
    if(p1->errorcode){
        int size = regerror(p1->errorcode,p1->r,NULL,0)+1;
        char *s = (char *)alloca(size);
        regerror(p1->errorcode,p1->r,s,1024);
        throw RUNT(EX_CORRUPT,"").set("bad regex in use: %s",s);
    }
    for(;;){
        int rv = regexec(p1->r,p0+off,1,&match,flags);
        if(rv == REG_NOMATCH)
            break;
        flags=REG_NOTBOL;
        Value *v = list->append();
        ArrayList<Value> *pair = Types::tList->set(v);
        Types::tInteger->set(pair->append(),match.rm_so+off);
        Types::tInteger->set(pair->append(),(match.rm_eo-match.rm_so));
        off += match.rm_eo;
    }
    a->pushval()->copy(&v);
}

%wordargs repl ssA|regex (subject repl regex -- result)
{
    regmatch_t match;
    int subjlen = strlen(p0);
    int repllen = strlen(p1);

    // first pass to calculate length
    bool hadMatches;
    int newlen = subjlen;
    int off=0;
    int flags = 0;
    for(;;){
        int rv = regexec(p2->r,p0+off,1,&match,flags);
        if(rv==REG_NOMATCH)
            break;
        flags=REG_NOTBOL;
        hadMatches = true;
        int start = match.rm_so;
        int end = match.rm_eo;
        if(start<0)break;
        int len = end-start;
        newlen+=(repllen-len);
        off += end;
    }

    // then do the replacements
    Value v;
    char *s = Types::tString->allocate(&v,newlen+1,Types::tString);

    int inoffset=0;
    int outoffset=0;
    flags = 0;
    if(hadMatches){ // skip if no matches in first pass
        for(;;){
            int rv = regexec(p2->r,p0+inoffset,1,&match,flags);
            if(rv==REG_NOMATCH)
                break;
            flags=REG_NOTBOL;
            int start = match.rm_so;
            int end = match.rm_eo;
            int len = end-start;

            // copy from current position in original string to
            // new string, the length of the next unreplaced section.
            memcpy(s+outoffset,p0+inoffset,start);

            // increment the offset into the output
            outoffset+=start;

            // copy in the replacement
            memcpy(s+outoffset,p1,repllen);

            // increment the offset into the original string, and
            // the offset into the output string
            inoffset+=start+len;
            outoffset+=repllen;
        }
    }
    // copy the remainder of the output string
    strcpy(s+outoffset,p0+inoffset);
    a->pushval()->copy(&v);
}

%wordargs split sA|regex (string regex -- list)
{
    regmatch_t match;
    Value v,*v2;
    char *s;
    ArrayList<Value> *list = Types::tList->set(&v);
    int off=0;
    int flags = 0;
    for(;;){
        int rv = regexec(p1->r,p0+off,1,&match,flags);
        if(rv == REG_NOMATCH)
            break;
        flags=REG_NOTBOL;
        v2 = list->append();
        s = Types::tString->allocate(v2,match.rm_so+1,Types::tString);
        memcpy(s,p0+off,match.rm_so);
        s[match.rm_so]=0;
        off += match.rm_eo;
    }
    v2 = list->append();
    Types::tString->set(v2,p0+off);

    a->pushval()->copy(&v);
}

%init
{
    fprintf(stderr,"Initialising REGEX plugin, %s %s\n",__DATE__,__TIME__);
}
<commit_msg>support for regex subexpr matches<commit_after>/**
 * @file regex.cpp
 * @brief  Brief description of file.
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <ctype.h>
#include <errno.h>
#include <regex.h>

#include <angort/angort.h>
#include <angort/hash.h>

using namespace angort;

%name regex
%shared

class Regex : public GarbageCollected {
public:
    regex_t *r;
    int errorcode; //zero or error code
    Regex(const char *s,bool icase){
        r = new regex_t;
        int f = REG_EXTENDED;
        if(icase) f|= REG_ICASE;
        errorcode = regcomp(r,s,f);
    }
    virtual ~Regex(){
        regfree(r);
    }
};

class RegexType : public GCType {
public:
    RegexType(){
        add("regex","REGX");
    }
    virtual ~RegexType(){};

    Regex *get(const Value *v) const {
        if(v->t != this)
            throw RUNT(EX_TYPE,"not a regex");
        return (Regex *)(v->v.gc);
    }

    Regex *set(Value *v,const char *s,bool icase){
        v->clr();
        v->t=this;
        Regex *r = new Regex(s,icase);
        v->v.gc = r;
        incRef(v);
        return r;
    }
};

static RegexType tR;

%type regex tR Regex

void docompile(Runtime *a,const char *p0,bool icase){
    char *s = strdup(p0); // copy to avoid pushval overwrite
    Value *v = a->pushval();
    Regex *r = tR.set(v,s,icase);
    free(s);

    if(r->errorcode){
        int size = regerror(r->errorcode,r->r,NULL,0)+1;
        char *s = (char *)alloca(size);
        regerror(r->errorcode,r->r,s,1024);
        throw RUNT(EX_FAILED,"").set("regex compile error: %s",s);
    }
}

%wordargs compile s (string -- compiled regex) compile a regex
{
    docompile(a,p0,false);
}

%wordargs compileicase s (string -- compiled regex) compile a regex (case independent)
{
    docompile(a,p0,true);
}

%wordargs chk A|regex (regex -- none or string) error check
{
    Value *v = a->pushval();
    if(p0->errorcode){
        int size = regerror(p0->errorcode,p0->r,NULL,0)+1;
        char *s = Types::tString->allocate(v,size,Types::tString);
        regerror(p0->errorcode,p0->r,s,1024);
    } else {
        a->pushNone();
    }
}

static void domatch(Runtime *a,const char *str,Regex *r,int nmatch){
    regmatch_t *match = (regmatch_t*)alloca(sizeof(regmatch_t)*(nmatch+1));
    Value v;
    ArrayList<Value> *list = Types::tList->set(&v);
    int off=0;
    int flags = 0;
    if(r->errorcode){
        int size = regerror(r->errorcode,r->r,NULL,0)+1;
        char *s = (char *)alloca(size);
        regerror(r->errorcode,r->r,s,1024);
        throw RUNT(EX_CORRUPT,"").set("bad regex in use: %s",s);
    }
    for(;;){
        int rv = regexec(r->r,str+off,nmatch,match,flags);
        if(rv == REG_NOMATCH)
            break;
        int eei=0;
        for(int i=0;i<nmatch;i++){
            if(match[i].rm_so>=0){
                Value *v = list->append();
                ArrayList<Value> *pair = Types::tList->set(v);
                Types::tInteger->set(pair->append(),match[i].rm_so+off);
                Types::tInteger->set(pair->append(),(match[i].rm_eo-match[i].rm_so));
                eei = match[i].rm_eo;
            }
        }
        off += eei;
    }
    a->pushval()->copy(&v);
}

%wordargs match sA|regex (str regex -- matchlist) match
{
    domatch(a,p0,p1,1);
}
%wordargs nmatch sAi|regex (str regex -- matchlist) match with n subexpressions
{
    domatch(a,p0,p1,p2+1);
}

%wordargs repl ssA|regex (subject repl regex -- result)
{
    regmatch_t match;
    int subjlen = strlen(p0);
    int repllen = strlen(p1);

    // first pass to calculate length
    bool hadMatches;
    int newlen = subjlen;
    int off=0;
    int flags = 0;
    for(;;){
        int rv = regexec(p2->r,p0+off,1,&match,flags);
        if(rv==REG_NOMATCH)
            break;
        flags=REG_NOTBOL;
        hadMatches = true;
        int start = match.rm_so;
        int end = match.rm_eo;
        if(start<0)break;
        int len = end-start;
        newlen+=(repllen-len);
        off += end;
    }

    // then do the replacements
    Value v;
    char *s = Types::tString->allocate(&v,newlen+1,Types::tString);

    int inoffset=0;
    int outoffset=0;
    flags = 0;
    if(hadMatches){ // skip if no matches in first pass
        for(;;){
            int rv = regexec(p2->r,p0+inoffset,1,&match,flags);
            if(rv==REG_NOMATCH)
                break;
            flags=REG_NOTBOL;
            int start = match.rm_so;
            int end = match.rm_eo;
            int len = end-start;

            // copy from current position in original string to
            // new string, the length of the next unreplaced section.
            memcpy(s+outoffset,p0+inoffset,start);

            // increment the offset into the output
            outoffset+=start;

            // copy in the replacement
            memcpy(s+outoffset,p1,repllen);

            // increment the offset into the original string, and
            // the offset into the output string
            inoffset+=start+len;
            outoffset+=repllen;
        }
    }
    // copy the remainder of the output string
    strcpy(s+outoffset,p0+inoffset);
    a->pushval()->copy(&v);
}

%wordargs split sA|regex (string regex -- list)
{
    regmatch_t match;
    Value v,*v2;
    char *s;
    ArrayList<Value> *list = Types::tList->set(&v);
    int off=0;
    int flags = 0;
    for(;;){
        int rv = regexec(p1->r,p0+off,1,&match,flags);
        if(rv == REG_NOMATCH)
            break;
        flags=REG_NOTBOL;
        v2 = list->append();
        s = Types::tString->allocate(v2,match.rm_so+1,Types::tString);
        memcpy(s,p0+off,match.rm_so);
        s[match.rm_so]=0;
        off += match.rm_eo;
    }
    v2 = list->append();
    Types::tString->set(v2,p0+off);

    a->pushval()->copy(&v);
}

%init
{
    fprintf(stderr,"Initialising REGEX plugin, %s %s\n",__DATE__,__TIME__);
}
<|endoftext|>


<commit_before>// Filename: test_proxy.cxx
// Created by:  drose (29Aug02)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license.  You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////

#include "pandabase.h"
#include "string_utils.h"
#include "queuedConnectionManager.h"
#include "queuedConnectionReader.h"
#include "connectionWriter.h"
#include "connection.h"
#include "pointerTo.h"
#include "datagram.h"

string proxy_server;
int proxy_port;
string data_server;
string url;

class HTTPClient {
public:
  HTTPClient();
  bool connect(const string &server, int port);
  bool send(const string &data);
  bool read(string &result);
  bool test_connection();
  void close();
  bool is_closed() const;

  QueuedConnectionManager _manager;
  QueuedConnectionReader _reader;
  ConnectionWriter _writer;
  PT(Connection) _connection;
};

HTTPClient::
HTTPClient() :
  _reader(&_manager, 0),
  _writer(&_manager, 0)
{
  _reader.set_raw_mode(true);
  _writer.set_raw_mode(true);
}

bool HTTPClient::
connect(const string &server, int port) {
  test_connection();
  nassertr(_connection.is_null(), false);

  _connection = _manager.open_TCP_client_connection(server, port, 1000);
  if (_connection.is_null()) {
    return false;
  }

  _reader.add_connection(_connection);
  return true;
}

bool HTTPClient::
send(const string &data) {
  test_connection();
  Datagram dg(data);
  return _writer.send(dg, _connection);
}

bool HTTPClient::
read(string &result) {
  test_connection();
  bool any_data = false;

  Datagram dg;
  while (_reader.data_available()) {
    if (_reader.get_data(dg)) {
      result += dg.get_message();
      any_data = true;
    }
  }

  return any_data;
}

bool HTTPClient::
test_connection() {
  bool okflag = true;
  while (_manager.reset_connection_available()) {
    PT(Connection) c;
    if (_manager.get_reset_connection(c)) {
      cerr << "lost connection: " << (void *)c << "\n";
      _manager.close_connection(_connection);
      _connection = NULL;
      okflag = false;
    }
  }

  return okflag;
}

void HTTPClient::
close() {
  test_connection();
  if (!_connection.is_null()) {
    _manager.close_connection(_connection);
    _connection = NULL;
  }
}

bool HTTPClient::
is_closed() const {
  return (_connection.is_null());
}

int
main(int argc, char *argv[]) {
  bool okflag = false;

  if (argc == 4 || argc == 5) {
    if (string_to_int(argv[2], proxy_port)) {
      proxy_server = argv[1];
      data_server = argv[3];
      if (argc >= 5) {
        url = argv[4];
      }
      okflag = true;
    }
  }

  if (!okflag) {
    cerr << "test_proxy proxy_server proxy_port data_server [url]\n";
    exit(1);
  }

  HTTPClient client;
  if (!client.connect(proxy_server, proxy_port)) {
    cerr << "Unable to connect to " << proxy_server << ":" << proxy_port << "\n";
    exit(1);
  }

  ostringstream request_strm;

  if (!url.empty()) {
    // Send a URL request to the proxy server.
    request_strm
      << "CONNECT " << data_server << " HTTP/1.0\n"
      << "\n"
      << "GET " << url << " HTTP/1.0\n"
      << "\n";

    /*
    request_strm
      << "GET " << url << " HTTP/1.1\n"
      << "Host: " << data_server << "\n"
      << "\n";*/
  } else {
    // Send a raw CONNECT request to the proxy server.
    request_strm
      << "CONNECT " << data_server << " HTTP/1.0\n"
      << "\n";
  }

  string request = request_strm.str();
  cerr << request;

  if (!client.send(request)) {
    cerr << "Error transmitting to proxy server.\n";
    exit(1);
  }

  cerr << "waiting.\n";

  while (!client.is_closed()) {
    string result;
    while (client.read(result)) {
      cerr << result;
      result = "";
    }
  }

  cerr << "terminating.\n";
  client.close();

  return (0);
}

<commit_msg>remove old test program<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: OPropertySet.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 00:44:32 $
 *
 *  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
 *
 ************************************************************************/
#ifndef CHART_OPROPERTYSET_HXX
#define CHART_OPROPERTYSET_HXX

// helper classes
#ifndef _CPPUHELPER_PROPSHLP_HXX
#include <cppuhelper/propshlp.hxx>
#endif
#ifndef _CPPUHELPER_INTERFACECONTAINER_HXX_
#include <cppuhelper/interfacecontainer.hxx>
#endif
#ifndef _CPPUHELPER_WEAK_HXX_
#include <cppuhelper/weak.hxx>
#endif

// interfaces and types
// #ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
// #include <com/sun/star/lang/XServiceInfo.hpp>
// #endif
#ifndef _COM_SUN_STAR_LANG_XTYPEPROVIDER_HPP_
#include <com/sun/star/lang/XTypeProvider.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSTATE_HPP_
#include <com/sun/star/beans/XPropertyState.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XMULTIPROPERTYSTATES_HPP_
#include <com/sun/star/beans/XMultiPropertyStates.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTY_HPP_
#include <com/sun/star/beans/Property.hpp>
#endif

#ifndef _COM_SUN_STAR_STYLE_XSTYLESUPPLIER_HPP_
#include <com/sun/star/style/XStyleSupplier.hpp>
#endif
// #ifndef _COM_SUN_STAR_BEANS_XFASTPROPERTYSTATE_HPP_
// #include <com/sun/star/beans/XFastPropertyState.hpp>
// #endif

#ifndef _OSL_MUTEX_HXX_
#include <osl/mutex.hxx>
#endif

#include <memory>

namespace property
{

namespace impl
{ class ImplOPropertySet; }

class OPropertySet :
    public ::cppu::OBroadcastHelper,
    // includes beans::XPropertySet, XMultiPropertySet and XFastPropertySet
    public ::cppu::OPropertySetHelper,
    // includes uno::XWeak (and XInterface, esp. ref-counting)
//     public virtual ::cppu::OWeakObject,

//     public virtual ::com::sun::star::lang::XServiceInfo,
    public ::com::sun::star::lang::XTypeProvider,
    public ::com::sun::star::beans::XPropertyState,
    public ::com::sun::star::beans::XMultiPropertyStates,
    public ::com::sun::star::style::XStyleSupplier
//     public ::com::sun::star::beans::XFastPropertyState
{
public:
    OPropertySet( ::osl::Mutex & rMutex );
    virtual ~OPropertySet();

protected:
    /** implement this method to provide default values for all properties
        supporting defaults.  If a property does not have a default value, you
        may throw an UnknownPropertyException.
     */
    virtual ::com::sun::star::uno::Any GetDefaultValue( sal_Int32 nHandle ) const
        throw(::com::sun::star::beans::UnknownPropertyException) = 0;

    /** The InfoHelper table contains all property names and types of
        this object.

        @return the object that provides information for the
                PropertySetInfo

        @see ::cppu::OPropertySetHelper
     */
    virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper() = 0;

    // ____ XPropertySet ____
    /** sample implementation using the InfoHelper:

        uno::Reference< beans::XPropertySetInfo > SAL_CALL
            OPropertySet::getPropertySetInfo()
                throw (uno::RuntimeException)
        {
            static uno::Reference< beans::XPropertySetInfo > xInfo;

            // /--
            ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
            if( !xInfo.is())
            {
                xInfo = ::cppu::OPropertySetHelper::createPropertySetInfo(
                    getInfoHelper());
            }

            return xInfo;
            // \--
        }

(The reason why this isn't implemented here is, that the static
        object is only valid per concrete PropertySet.  Otherwise all
        PropertySets derived from this base calss would have the same
        properties.)

        @see ::cppu::OPropertySetHelper
    */
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL
        getPropertySetInfo()
        throw (::com::sun::star::uno::RuntimeException) = 0;

    /** Try to convert the value rValue to the type required by the
        property associated with nHandle.

        Overload this method to take influence in modification of properties.

        If the conversion changed , </TRUE> is returned and the converted value
        is in rConvertedValue.  The former value is contained in
        rOldValue.

        After this call returns successfully, the vetoable listeners are
        notified.

        @throws IllegalArgumentException, if the conversion was not successful,
                or if there is no corresponding property to the given handle.

        @param rConvertedValue the converted value. Only set if return is true.
        @param rOldValue the old value. Only set if return is true.
        @param nHandle the handle of the property.

        @return true, if the conversion was successful and converted value
                differs from the old value.

        @see ::cppu::OPropertySetHelper
     */
    virtual sal_Bool SAL_CALL convertFastPropertyValue
        ( ::com::sun::star::uno::Any & rConvertedValue,
          ::com::sun::star::uno::Any & rOldValue,
          sal_Int32 nHandle,
          const ::com::sun::star::uno::Any& rValue )
        throw (::com::sun::star::lang::IllegalArgumentException);

    /** The same as setFastProperyValue; nHandle is always valid.
        The changes must not be broadcasted in this method.

        @attention
        Although you are permitted to throw any UNO exception, only the following
        are valid for usage:
        -- ::com::sun::star::beans::UnknownPropertyException
        -- ::com::sun::star::beans::PropertyVetoException
        -- ::com::sun::star::lang::IllegalArgumentException
        -- ::com::sun::star::lang::WrappedTargetException
        -- ::com::sun::star::uno::RuntimeException

        @param nHandle handle
        @param rValue  value

        @see ::cppu::OPropertySetHelper
    */
    virtual void SAL_CALL setFastPropertyValue_NoBroadcast
        ( sal_Int32 nHandle,
          const ::com::sun::star::uno::Any& rValue )
        throw (::com::sun::star::uno::Exception);

    /**
       The same as getFastProperyValue, but return the value through rValue and
       nHandle is always valid.

        @see ::cppu::OPropertySetHelper
     */
    virtual void SAL_CALL getFastPropertyValue
        ( ::com::sun::star::uno::Any& rValue,
          sal_Int32 nHandle ) const;

    /// make original interface function visible again
    using ::com::sun::star::beans::XFastPropertySet::getFastPropertyValue;

    // ========================================
    // Interfaces
    // ========================================

    // ____ XInterface ____
    virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& aType )
        throw (::com::sun::star::uno::RuntimeException);
//     virtual void SAL_CALL acquire() throw ();
//     virtual void SAL_CALL release() throw ();

    // ____ XServiceInfo ____
//     virtual ::rtl::OUString SAL_CALL
//         getImplementationName()
//         throw (::com::sun::star::uno::RuntimeException);
//     virtual sal_Bool SAL_CALL
//         supportsService( const ::rtl::OUString& ServiceName )
//         throw (::com::sun::star::uno::RuntimeException);
//     virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
//         getSupportedServiceNames()
//         throw (::com::sun::star::uno::RuntimeException);

    // ____ XTypeProvider ____
    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL
        getTypes()
        throw (::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL
        getImplementationId()
        throw (::com::sun::star::uno::RuntimeException);

    // ____ XPropertyState ____
    virtual ::com::sun::star::beans::PropertyState SAL_CALL
        getPropertyState( const ::rtl::OUString& PropertyName )
        throw (::com::sun::star::beans::UnknownPropertyException,
               ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyState > SAL_CALL
        getPropertyStates( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyName )
        throw (::com::sun::star::beans::UnknownPropertyException,
               ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL
        setPropertyToDefault( const ::rtl::OUString& PropertyName )
        throw (::com::sun::star::beans::UnknownPropertyException,
               ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Any SAL_CALL
        getPropertyDefault( const ::rtl::OUString& aPropertyName )
        throw (::com::sun::star::beans::UnknownPropertyException,
               ::com::sun::star::lang::WrappedTargetException,
               ::com::sun::star::uno::RuntimeException);

    // ____ XMultiPropertyStates ____
    // Note: getPropertyStates() is already implemented in XPropertyState with the
    // same signature
    virtual void SAL_CALL
        setAllPropertiesToDefault()
        throw (::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL
        setPropertiesToDefault( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames )
        throw (::com::sun::star::beans::UnknownPropertyException,
               ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > SAL_CALL
        getPropertyDefaults( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames )
        throw (::com::sun::star::beans::UnknownPropertyException,
               ::com::sun::star::lang::WrappedTargetException,
               ::com::sun::star::uno::RuntimeException);

    // ____ XStyleSupplier ____
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::style::XStyle > SAL_CALL getStyle()
        throw (::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL setStyle( const ::com::sun::star::uno::Reference< ::com::sun::star::style::XStyle >& xStyle )
        throw (::com::sun::star::lang::IllegalArgumentException,
               ::com::sun::star::uno::RuntimeException);

    // ____ XFastPropertyState ____
//     virtual ::com::sun::star::beans::PropertyState SAL_CALL getFastPropertyState( sal_Int32 nHandle )
//         throw (::com::sun::star::beans::UnknownPropertyException,
//                ::com::sun::star::uno::RuntimeException);
//     virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyState > SAL_CALL getFastPropertyStates( const ::com::sun::star::uno::Sequence< sal_Int32 >& aHandles )
//         throw (::com::sun::star::beans::UnknownPropertyException,
//                ::com::sun::star::uno::RuntimeException);
//     virtual void SAL_CALL setFastPropertyToDefault( sal_Int32 nHandle )
//         throw (::com::sun::star::beans::UnknownPropertyException,
//                ::com::sun::star::uno::RuntimeException);
//     virtual ::com::sun::star::uno::Any SAL_CALL getFastPropertyDefault( sal_Int32 nHandle )
//         throw (::com::sun::star::beans::UnknownPropertyException,
//                ::com::sun::star::lang::WrappedTargetException,
//                ::com::sun::star::uno::RuntimeException);

private:
    /// reference to mutex of class deriving from here
    ::osl::Mutex &   m_rMutex;

    /// pImpl idiom implementation
    ::std::auto_ptr< impl::ImplOPropertySet > m_pImplProperties;
};

} //  namespace property

// CHART_OPROPERTYSET_HXX
#endif
<commit_msg>INTEGRATION: CWS chart2mst3 (1.2.4); FILE MERGED 2005/11/15 15:30:27 bm 1.2.4.6: garbage collection, disposing, reference release issues 2005/11/03 13:38:45 bm 1.2.4.5: do not notify change to parent object in _NoBroadcast method 2005/11/03 11:57:03 bm 1.2.4.4: +firePropertyChangeEvent for notifying property changes 2005/10/07 11:44:17 bm 1.2.4.3: RESYNC: (1.2-1.3); FILE MERGED 2005/09/23 15:24:10 iha 1.2.4.2: #i55000# crash caused by dead reference to mutex 2005/03/30 16:31:05 bm 1.2.4.1: make model cloneable (+first undo implementation)<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: OPropertySet.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: vg $ $Date: 2007-05-22 18:20:42 $
 *
 *  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
 *
 ************************************************************************/
#ifndef CHART_OPROPERTYSET_HXX
#define CHART_OPROPERTYSET_HXX

// helper classes
#ifndef _CPPUHELPER_PROPSHLP_HXX
#include <cppuhelper/propshlp.hxx>
#endif
#ifndef _CPPUHELPER_INTERFACECONTAINER_HXX_
#include <cppuhelper/interfacecontainer.hxx>
#endif
#ifndef _CPPUHELPER_WEAK_HXX_
#include <cppuhelper/weak.hxx>
#endif

// interfaces and types
// #ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
// #include <com/sun/star/lang/XServiceInfo.hpp>
// #endif
#ifndef _COM_SUN_STAR_LANG_XTYPEPROVIDER_HPP_
#include <com/sun/star/lang/XTypeProvider.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSTATE_HPP_
#include <com/sun/star/beans/XPropertyState.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XMULTIPROPERTYSTATES_HPP_
#include <com/sun/star/beans/XMultiPropertyStates.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTY_HPP_
#include <com/sun/star/beans/Property.hpp>
#endif

#ifndef _COM_SUN_STAR_STYLE_XSTYLESUPPLIER_HPP_
#include <com/sun/star/style/XStyleSupplier.hpp>
#endif
// #ifndef _COM_SUN_STAR_BEANS_XFASTPROPERTYSTATE_HPP_
// #include <com/sun/star/beans/XFastPropertyState.hpp>
// #endif

#ifndef _OSL_MUTEX_HXX_
#include <osl/mutex.hxx>
#endif

#include <memory>

namespace property
{

namespace impl
{ class ImplOPropertySet; }

class OPropertySet :
    public ::cppu::OBroadcastHelper,
    // includes beans::XPropertySet, XMultiPropertySet and XFastPropertySet
    public ::cppu::OPropertySetHelper,
    // includes uno::XWeak (and XInterface, esp. ref-counting)
//     public virtual ::cppu::OWeakObject,

//     public virtual ::com::sun::star::lang::XServiceInfo,
    public ::com::sun::star::lang::XTypeProvider,
    public ::com::sun::star::beans::XPropertyState,
    public ::com::sun::star::beans::XMultiPropertyStates,
    public ::com::sun::star::style::XStyleSupplier
//     public ::com::sun::star::beans::XFastPropertyState
{
public:
    OPropertySet( ::osl::Mutex & rMutex );
    virtual ~OPropertySet();

protected:
    explicit OPropertySet( const OPropertySet & rOther, ::osl::Mutex & rMutex );

    /** implement this method to provide default values for all properties
        supporting defaults.  If a property does not have a default value, you
        may throw an UnknownPropertyException.
     */
    virtual ::com::sun::star::uno::Any GetDefaultValue( sal_Int32 nHandle ) const
        throw(::com::sun::star::beans::UnknownPropertyException) = 0;

    /** The InfoHelper table contains all property names and types of
        this object.

        @return the object that provides information for the
                PropertySetInfo

        @see ::cppu::OPropertySetHelper
     */
    virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper() = 0;

    // ____ XPropertySet ____
    /** sample implementation using the InfoHelper:

        uno::Reference< beans::XPropertySetInfo > SAL_CALL
            OPropertySet::getPropertySetInfo()
                throw (uno::RuntimeException)
        {
            static uno::Reference< beans::XPropertySetInfo > xInfo;

            // /--
            ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
            if( !xInfo.is())
            {
                xInfo = ::cppu::OPropertySetHelper::createPropertySetInfo(
                    getInfoHelper());
            }

            return xInfo;
            // \--
        }

(The reason why this isn't implemented here is, that the static
        object is only valid per concrete PropertySet.  Otherwise all
        PropertySets derived from this base calss would have the same
        properties.)

        @see ::cppu::OPropertySetHelper
    */
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL
        getPropertySetInfo()
        throw (::com::sun::star::uno::RuntimeException) = 0;

    /** Try to convert the value rValue to the type required by the
        property associated with nHandle.

        Overload this method to take influence in modification of properties.

        If the conversion changed , </TRUE> is returned and the converted value
        is in rConvertedValue.  The former value is contained in
        rOldValue.

        After this call returns successfully, the vetoable listeners are
        notified.

        @throws IllegalArgumentException, if the conversion was not successful,
                or if there is no corresponding property to the given handle.

        @param rConvertedValue the converted value. Only set if return is true.
        @param rOldValue the old value. Only set if return is true.
        @param nHandle the handle of the property.

        @return true, if the conversion was successful and converted value
                differs from the old value.

        @see ::cppu::OPropertySetHelper
     */
    virtual sal_Bool SAL_CALL convertFastPropertyValue
        ( ::com::sun::star::uno::Any & rConvertedValue,
          ::com::sun::star::uno::Any & rOldValue,
          sal_Int32 nHandle,
          const ::com::sun::star::uno::Any& rValue )
        throw (::com::sun::star::lang::IllegalArgumentException);

    /** The same as setFastProperyValue; nHandle is always valid.
        The changes must not be broadcasted in this method.

        @attention
        Although you are permitted to throw any UNO exception, only the following
        are valid for usage:
        -- ::com::sun::star::beans::UnknownPropertyException
        -- ::com::sun::star::beans::PropertyVetoException
        -- ::com::sun::star::lang::IllegalArgumentException
        -- ::com::sun::star::lang::WrappedTargetException
        -- ::com::sun::star::uno::RuntimeException

        @param nHandle handle
        @param rValue  value

        @see ::cppu::OPropertySetHelper
    */
    virtual void SAL_CALL setFastPropertyValue_NoBroadcast
        ( sal_Int32 nHandle,
          const ::com::sun::star::uno::Any& rValue )
        throw (::com::sun::star::uno::Exception);

    /**
       The same as getFastProperyValue, but return the value through rValue and
       nHandle is always valid.

        @see ::cppu::OPropertySetHelper
     */
    virtual void SAL_CALL getFastPropertyValue
        ( ::com::sun::star::uno::Any& rValue,
          sal_Int32 nHandle ) const;

    /// make original interface function visible again
    using ::com::sun::star::beans::XFastPropertySet::getFastPropertyValue;

    /** implement this method in derived classes to get called when properties
        change.
     */
    virtual void firePropertyChangeEvent();

    /// call this when a derived component is disposed
    virtual void disposePropertySet();

    // ========================================
    // Interfaces
    // ========================================

    // ____ XInterface ____
    virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& aType )
        throw (::com::sun::star::uno::RuntimeException);
//     virtual void SAL_CALL acquire() throw ();
//     virtual void SAL_CALL release() throw ();

    // ____ XServiceInfo ____
//     virtual ::rtl::OUString SAL_CALL
//         getImplementationName()
//         throw (::com::sun::star::uno::RuntimeException);
//     virtual sal_Bool SAL_CALL
//         supportsService( const ::rtl::OUString& ServiceName )
//         throw (::com::sun::star::uno::RuntimeException);
//     virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
//         getSupportedServiceNames()
//         throw (::com::sun::star::uno::RuntimeException);

    // ____ XTypeProvider ____
    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL
        getTypes()
        throw (::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL
        getImplementationId()
        throw (::com::sun::star::uno::RuntimeException);

    // ____ XPropertyState ____
    virtual ::com::sun::star::beans::PropertyState SAL_CALL
        getPropertyState( const ::rtl::OUString& PropertyName )
        throw (::com::sun::star::beans::UnknownPropertyException,
               ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyState > SAL_CALL
        getPropertyStates( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyName )
        throw (::com::sun::star::beans::UnknownPropertyException,
               ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL
        setPropertyToDefault( const ::rtl::OUString& PropertyName )
        throw (::com::sun::star::beans::UnknownPropertyException,
               ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Any SAL_CALL
        getPropertyDefault( const ::rtl::OUString& aPropertyName )
        throw (::com::sun::star::beans::UnknownPropertyException,
               ::com::sun::star::lang::WrappedTargetException,
               ::com::sun::star::uno::RuntimeException);

    // ____ XMultiPropertyStates ____
    // Note: getPropertyStates() is already implemented in XPropertyState with the
    // same signature
    virtual void SAL_CALL
        setAllPropertiesToDefault()
        throw (::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL
        setPropertiesToDefault( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames )
        throw (::com::sun::star::beans::UnknownPropertyException,
               ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > SAL_CALL
        getPropertyDefaults( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames )
        throw (::com::sun::star::beans::UnknownPropertyException,
               ::com::sun::star::lang::WrappedTargetException,
               ::com::sun::star::uno::RuntimeException);

    // ____ XStyleSupplier ____
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::style::XStyle > SAL_CALL getStyle()
        throw (::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL setStyle( const ::com::sun::star::uno::Reference< ::com::sun::star::style::XStyle >& xStyle )
        throw (::com::sun::star::lang::IllegalArgumentException,
               ::com::sun::star::uno::RuntimeException);

    // ____ XFastPropertyState ____
//     virtual ::com::sun::star::beans::PropertyState SAL_CALL getFastPropertyState( sal_Int32 nHandle )
//         throw (::com::sun::star::beans::UnknownPropertyException,
//                ::com::sun::star::uno::RuntimeException);
//     virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyState > SAL_CALL getFastPropertyStates( const ::com::sun::star::uno::Sequence< sal_Int32 >& aHandles )
//         throw (::com::sun::star::beans::UnknownPropertyException,
//                ::com::sun::star::uno::RuntimeException);
//     virtual void SAL_CALL setFastPropertyToDefault( sal_Int32 nHandle )
//         throw (::com::sun::star::beans::UnknownPropertyException,
//                ::com::sun::star::uno::RuntimeException);
//     virtual ::com::sun::star::uno::Any SAL_CALL getFastPropertyDefault( sal_Int32 nHandle )
//         throw (::com::sun::star::beans::UnknownPropertyException,
//                ::com::sun::star::lang::WrappedTargetException,
//                ::com::sun::star::uno::RuntimeException);

    // ____ XMultiPropertySet ____
    virtual void SAL_CALL setPropertyValues(
        const ::com::sun::star::uno::Sequence< ::rtl::OUString >& PropertyNames,
        const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& Values )
        throw(::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);

    // ____ XFastPropertySet ____
    virtual void SAL_CALL setFastPropertyValue( sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue )
        throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);

    // Note: it is assumed that the base class implements setPropertyValue by
    // using setFastPropertyValue

private:
    /// reference to mutex of class deriving from here
    ::osl::Mutex &   m_rMutex;

    /// pImpl idiom implementation
    ::std::auto_ptr< impl::ImplOPropertySet > m_pImplProperties;
};

} //  namespace property

// CHART_OPROPERTYSET_HXX
#endif
<|endoftext|>


<commit_before>// $Id: fe_clough.C,v 1.5 2005-02-28 16:35:25 roystgnr Exp $

// The libMesh Finite Element Library.
// Copyright (C) 2002-2005  Benjamin S. Kirk, John W. Peterson

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// Local includes
#include "dense_matrix.h"
#include "dense_vector.h"
#include "dof_map.h"
#include "elem.h"
#include "fe.h"
#include "fe_interface.h"
#include "quadrature_clough.h"

// ------------------------------------------------------------
// Hierarchic-specific implementations
template <unsigned int Dim, FEFamily T>
void FE<Dim,T>::nodal_soln(const Elem* elem,
			   const Order order,
			   const std::vector<Number>& elem_soln,
			   std::vector<Number>&       nodal_soln)
{
  const unsigned int n_nodes = elem->n_nodes();

  const ElemType type = elem->type();

  nodal_soln.resize(n_nodes);

  switch (order)
    {
      // Piecewise cubic shape functions only
    case THIRD:
      {

	const unsigned int n_sf =
	  FE<Dim,T>::n_shape_functions(type, order);

	for (unsigned int n=0; n<n_nodes; n++)
	  {
	    const Point mapped_point = FE<Dim,T>::inverse_map(elem,
							      elem->point(n));

	    assert (elem_soln.size() == n_sf);

	    // Zero before summation
	    nodal_soln[n] = 0;

	    // u_i = Sum (alpha_i phi_i)
	    for (unsigned int i=0; i<n_sf; i++)
	      nodal_soln[n] += elem_soln[i]*FE<Dim,T>::shape(elem,
							     order,
							     i,
							     mapped_point);
	  }

	return;
      }

    default:
      {
	error();
      }
    }
}

template <unsigned int Dim, FEFamily T>
unsigned int FE<Dim,T>::n_dofs(const ElemType t, const Order o)
{
  switch (o)
    {
      // Piecewise cubic Clough-Tocher element
    case THIRD:
      {
	switch (t)
	  {
	  case TRI6:
	    return 12;

	  default:
	    {
#ifdef DEBUG
	      std::cerr << "ERROR: Bad ElemType = " << t
			<< " for " << o << "th order approximation!"
			<< std::endl;
#endif
	      error();
	    }
	  }
      }

    default:
      {
	error();
      }
    }

  error();
  return 0;
}

template <unsigned int Dim, FEFamily T>
unsigned int FE<Dim,T>::n_dofs_at_node(const ElemType t,
				       const Order o,
				       const unsigned int n)
{
  switch (o)
    {
      // The third-order hierarchic shape functions
    case THIRD:
      {
	switch (t)
	  {
	    // The 2D Clough-Tocher defined on a 6-noded triangle
	  case TRI6:
	    {
	      switch (n)
		{
		case 0:
		case 1:
		case 2:
		  return 3;

		case 3:
		case 4:
		case 5:
		  return 1;

		default:
		  error();
		}
	    }

	  default:
	    {
#ifdef DEBUG
	      std::cerr << "ERROR: Bad ElemType = " << t
			<< " for " << o << "th order approximation!"
			<< std::endl;
#endif
	      error();
	    }

	  }
      }
    default:
      {
	error();
      }
    }

  error();

  return 0;
}

template <unsigned int Dim, FEFamily T>
unsigned int FE<Dim,T>::n_dofs_per_elem(const ElemType t,
					const Order o)
{
  switch (o)
    {
      // The third-order Clough-Tocher shape functions
    case THIRD:
      {
	switch (t)
	  {
	    // The 2D hierarchic defined on a 6-noded triangle
	  case TRI6:
	    return 0;

	  default:
	    {
#ifdef DEBUG
	      std::cerr << "ERROR: Bad ElemType = " << t
			<< " for " << o << "th order approximation!"
			<< std::endl;
#endif
	      error();
	    }

	  }
      }
      // Otherwise no DOFS per element
    default:
      error();
      return 0;
    }
}

template <unsigned int Dim, FEFamily T>
void FE<Dim,T>::compute_constraints (std::map<unsigned int,
				     std::map<unsigned int, float> > &
				     constraints,
				     DofMap &dof_map,
				     const unsigned int variable_number,
				     const Elem* elem)
{
#ifdef ENABLE_AMR
  // Only constrain elements in 2,3D.
  if (Dim == 1)
    return;

  assert (elem != NULL);

  const FEType& fe_type = dof_map.variable_type(variable_number);

  AutoPtr<FEBase> my_fe (FEBase::build(Dim, fe_type));
  AutoPtr<FEBase> parent_fe (FEBase::build(Dim, fe_type));

  QClough my_qface(Dim-1, fe_type.default_quadrature_order());
  my_fe->attach_quadrature_rule (&my_qface);
  std::vector<Point> parent_qface;

  const std::vector<Real>& JxW = my_fe->get_JxW();
  const std::vector<Point>& q_point = my_fe->get_xyz();
  const std::vector<std::vector<Real> >& phi = my_fe->get_phi();
  const std::vector<std::vector<Real> >& parent_phi =
		  parent_fe->get_phi();
  const std::vector<Point>& face_normals = my_fe->get_normals();
  const std::vector<std::vector<RealGradient> >& dphi =
		  my_fe->get_dphi();
  const std::vector<std::vector<RealGradient> >& parent_dphi =
		  parent_fe->get_dphi();
  std::vector<unsigned int> child_dof_indices, parent_dof_indices;
  std::vector<unsigned int> my_side_dofs, parent_side_dofs;

  DenseMatrix<Number> Ke;
  DenseVector<Number> Fe;
  std::vector<DenseVector<Number> > Ue;

  // Look at the element faces.  Check to see if we need to
  // build constraints.
  for (unsigned int s=0; s<elem->n_sides(); s++)
    if (elem->neighbor(s) != NULL)
      // constrain dofs shared between
      // this element and ones coarser
      // than this element.
      if (elem->neighbor(s)->level() < elem->level())
        {
          // Get pointers to the elements of interest and its parent.
          const Elem* parent = elem->parent();
	  unsigned int s_parent = s;

          // This can't happen...  Only level-0 elements have NULL
          // parents, and no level-0 elements can be at a higher
          // level than their neighbors!
          assert (parent != NULL);

	  my_fe->reinit(elem, s);

	  dof_map.dof_indices (elem, child_dof_indices);
	  dof_map.dof_indices (parent, parent_dof_indices);

	  const unsigned int n_qp = my_qface.n_points();

	  FEInterface::inverse_map (Dim, fe_type, parent, q_point,
				    parent_qface);

	  parent_fe->reinit(parent, &parent_qface);

	  // We're only concerned with DOFs whose values and/or first
	  // derivatives are supported on side nodes
	  dofs_on_side(elem, fe_type.order, s, my_side_dofs);
	  dofs_on_side(parent, fe_type.order, s_parent, parent_side_dofs);
	  const unsigned int n_side_dofs = my_side_dofs.size();
	  assert(n_side_dofs == parent_side_dofs.size());

	  Ke.resize (n_side_dofs, n_side_dofs);
	  Ue.resize(n_side_dofs);

	  // Form the projection matrix, (inner product of fine basis
	  // functions against fine test functions)
	  for (unsigned int is = 0; is != n_side_dofs; ++is)
	    {
	      const unsigned int i = my_side_dofs[is];
	      for (unsigned int js = 0; js != n_side_dofs; ++js)
	        {
	          const unsigned int j = my_side_dofs[js];
		  for (unsigned int qp = 0; qp != n_qp; ++qp)
		    Ke(is,js) += JxW[qp] * (phi[i][qp] * phi[j][qp] +
					    (dphi[i][qp] *
					     face_normals[qp]) *
					    (dphi[j][qp] *
					     face_normals[qp]));
		}
	    }

	  // Form the right hand sides, (inner product of coarse basis
	  // functions against fine test functions)
	  for (unsigned int is = 0; is != n_side_dofs; ++is)
	    {
	      const unsigned int i = parent_side_dofs[is];
	      Fe.resize (n_side_dofs);
	      for (unsigned int js = 0; js != n_side_dofs; ++js)
		{
	          const unsigned int j = my_side_dofs[js];
	          for (unsigned int qp = 0; qp != n_qp; ++qp)
		    Fe(js) += JxW[qp] * (parent_phi[i][qp] *
					 phi[j][qp] +
					 (parent_dphi[i][qp] *
					  face_normals[qp]) *
					 (dphi[j][qp] *
					  face_normals[qp]));
		}
	      Ke.cholesky_solve(Fe, Ue[is]);
	    }
	  for (unsigned int is = 0; is != n_side_dofs; ++is)
	    {
	      const unsigned int i = parent_side_dofs[is];
	      const unsigned int their_dof_g = parent_dof_indices[i];
	      for (unsigned int js = 0; js != n_side_dofs; ++js)
	        {
	          const unsigned int j = my_side_dofs[js];
	          const unsigned int my_dof_g = child_dof_indices[j];
		  const Real their_dof_value = Ue[is](js);
		  if (their_dof_g == my_dof_g)
		    {
		      assert(std::abs(their_dof_value-1.) < 1.e-5);
		      for (unsigned int k = 0; k != n_side_dofs; ++k)
		        assert(k == is || std::abs(Ue[k](is)) < 1.e-5);
		      continue;
		    }
		  if (std::abs(their_dof_value) < 1.e-5)
		    continue;

		  DofMap::DofConstraintRow& constraint_row =
				  constraints[my_dof_g];

		  constraint_row.insert(std::make_pair(their_dof_g,
						       static_cast<float>(their_dof_value)));
	        }
	    }
	}
#endif
}

template <unsigned int Dim, FEFamily T>
bool FE<Dim,T>::shapes_need_reinit() const
{
  return true;
}

//--------------------------------------------------------------
// Explicit instantiations
template class FE<1,CLOUGH>;  // FIXME: 1D Not yet functional!
template class FE<2,CLOUGH>;
template class FE<3,CLOUGH>;  // FIXME: 2D Not yet functional!
<commit_msg><commit_after>// $Id: fe_clough.C,v 1.6 2005-02-28 19:05:58 roystgnr Exp $

// The libMesh Finite Element Library.
// Copyright (C) 2002-2005  Benjamin S. Kirk, John W. Peterson

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// Local includes
#include "dense_matrix.h"
#include "dense_vector.h"
#include "dof_map.h"
#include "elem.h"
#include "fe.h"
#include "fe_interface.h"
#include "quadrature_clough.h"

// ------------------------------------------------------------
// Hierarchic-specific implementations
template <unsigned int Dim, FEFamily T>
void FE<Dim,T>::nodal_soln(const Elem* elem,
			   const Order order,
			   const std::vector<Number>& elem_soln,
			   std::vector<Number>&       nodal_soln)
{
  const unsigned int n_nodes = elem->n_nodes();

  const ElemType type = elem->type();

  nodal_soln.resize(n_nodes);

  switch (order)
    {
      // Piecewise cubic shape functions only
    case THIRD:
      {

	const unsigned int n_sf =
	  FE<Dim,T>::n_shape_functions(type, order);

	for (unsigned int n=0; n<n_nodes; n++)
	  {
	    const Point mapped_point = FE<Dim,T>::inverse_map(elem,
							      elem->point(n));

	    assert (elem_soln.size() == n_sf);

	    // Zero before summation
	    nodal_soln[n] = 0;

	    // u_i = Sum (alpha_i phi_i)
	    for (unsigned int i=0; i<n_sf; i++)
	      nodal_soln[n] += elem_soln[i]*FE<Dim,T>::shape(elem,
							     order,
							     i,
							     mapped_point);
	  }

	return;
      }

    default:
      {
	error();
      }
    }
}

template <unsigned int Dim, FEFamily T>
unsigned int FE<Dim,T>::n_dofs(const ElemType t, const Order o)
{
  switch (o)
    {
      // Piecewise cubic Clough-Tocher element
    case THIRD:
      {
	switch (t)
	  {
	  case TRI6:
	    return 12;

	  default:
	    {
#ifdef DEBUG
	      std::cerr << "ERROR: Bad ElemType = " << t
			<< " for " << o << "th order approximation!"
			<< std::endl;
#endif
	      error();
	    }
	  }
      }

    default:
      {
	error();
      }
    }

  error();
  return 0;
}

template <unsigned int Dim, FEFamily T>
unsigned int FE<Dim,T>::n_dofs_at_node(const ElemType t,
				       const Order o,
				       const unsigned int n)
{
  switch (o)
    {
      // The third-order hierarchic shape functions
    case THIRD:
      {
	switch (t)
	  {
	    // The 2D Clough-Tocher defined on a 6-noded triangle
	  case TRI6:
	    {
	      switch (n)
		{
		case 0:
		case 1:
		case 2:
		  return 3;

		case 3:
		case 4:
		case 5:
		  return 1;

		default:
		  error();
		}
	    }

	  default:
	    {
#ifdef DEBUG
	      std::cerr << "ERROR: Bad ElemType = " << t
			<< " for " << o << "th order approximation!"
			<< std::endl;
#endif
	      error();
	    }

	  }
      }
    default:
      {
	error();
      }
    }

  error();

  return 0;
}

template <unsigned int Dim, FEFamily T>
unsigned int FE<Dim,T>::n_dofs_per_elem(const ElemType t,
					const Order o)
{
  switch (o)
    {
      // The third-order Clough-Tocher shape functions
    case THIRD:
      {
	switch (t)
	  {
	    // The 2D hierarchic defined on a 6-noded triangle
	  case TRI6:
	    return 0;

	  default:
	    {
#ifdef DEBUG
	      std::cerr << "ERROR: Bad ElemType = " << t
			<< " for " << o << "th order approximation!"
			<< std::endl;
#endif
	      error();
	    }

	  }
      }
      // Otherwise no DOFS per element
    default:
      error();
      return 0;
    }
}

template <unsigned int Dim, FEFamily T>
void FE<Dim,T>::compute_constraints (std::map<unsigned int,
				     std::map<unsigned int, float> > &
				     constraints,
				     DofMap &dof_map,
				     const unsigned int variable_number,
				     const Elem* elem)
{
#ifdef ENABLE_AMR
  // Only constrain elements in 2,3D.
  if (Dim == 1)
    return;

  assert (elem != NULL);

  const FEType& fe_type = dof_map.variable_type(variable_number);

  AutoPtr<FEBase> my_fe (FEBase::build(Dim, fe_type));
  AutoPtr<FEBase> parent_fe (FEBase::build(Dim, fe_type));

  QClough my_qface(Dim-1, fe_type.default_quadrature_order());
  my_fe->attach_quadrature_rule (&my_qface);
  std::vector<Point> parent_qface;

  const std::vector<Real>& JxW = my_fe->get_JxW();
  const std::vector<Point>& q_point = my_fe->get_xyz();
  const std::vector<std::vector<Real> >& phi = my_fe->get_phi();
  const std::vector<std::vector<Real> >& parent_phi =
		  parent_fe->get_phi();
  const std::vector<Point>& face_normals = my_fe->get_normals();
  const std::vector<std::vector<RealGradient> >& dphi =
		  my_fe->get_dphi();
  const std::vector<std::vector<RealGradient> >& parent_dphi =
		  parent_fe->get_dphi();
  std::vector<unsigned int> child_dof_indices, parent_dof_indices;
  std::vector<unsigned int> my_side_dofs, parent_side_dofs;

  DenseMatrix<Number> Ke;
  DenseVector<Number> Fe;
  std::vector<DenseVector<Number> > Ue;

  // Look at the element faces.  Check to see if we need to
  // build constraints.
  for (unsigned int s=0; s<elem->n_sides(); s++)
    if (elem->neighbor(s) != NULL)
      // constrain dofs shared between
      // this element and ones coarser
      // than this element.
      if (elem->neighbor(s)->level() < elem->level())
        {
          // Get pointers to the elements of interest and its parent.
          const Elem* parent = elem->parent();
	  unsigned int s_parent = s;

          // This can't happen...  Only level-0 elements have NULL
          // parents, and no level-0 elements can be at a higher
          // level than their neighbors!
          assert (parent != NULL);

	  my_fe->reinit(elem, s);

	  dof_map.dof_indices (elem, child_dof_indices,
			       variable_number);
	  dof_map.dof_indices (parent, parent_dof_indices,
			       variable_number);

	  const unsigned int n_qp = my_qface.n_points();

	  FEInterface::inverse_map (Dim, fe_type, parent, q_point,
				    parent_qface);

	  parent_fe->reinit(parent, &parent_qface);

	  // We're only concerned with DOFs whose values and/or first
	  // derivatives are supported on side nodes
	  dofs_on_side(elem, fe_type.order, s, my_side_dofs);
	  dofs_on_side(parent, fe_type.order, s_parent, parent_side_dofs);
	  const unsigned int n_side_dofs = my_side_dofs.size();
	  assert(n_side_dofs == parent_side_dofs.size());

	  Ke.resize (n_side_dofs, n_side_dofs);
	  Ue.resize(n_side_dofs);

	  // Form the projection matrix, (inner product of fine basis
	  // functions against fine test functions)
	  for (unsigned int is = 0; is != n_side_dofs; ++is)
	    {
	      const unsigned int i = my_side_dofs[is];
	      for (unsigned int js = 0; js != n_side_dofs; ++js)
	        {
	          const unsigned int j = my_side_dofs[js];
		  for (unsigned int qp = 0; qp != n_qp; ++qp)
		    Ke(is,js) += JxW[qp] * (phi[i][qp] * phi[j][qp] +
					    (dphi[i][qp] *
					     face_normals[qp]) *
					    (dphi[j][qp] *
					     face_normals[qp]));
		}
	    }

	  // Form the right hand sides, (inner product of coarse basis
	  // functions against fine test functions)
	  for (unsigned int is = 0; is != n_side_dofs; ++is)
	    {
	      const unsigned int i = parent_side_dofs[is];
	      Fe.resize (n_side_dofs);
	      for (unsigned int js = 0; js != n_side_dofs; ++js)
		{
	          const unsigned int j = my_side_dofs[js];
	          for (unsigned int qp = 0; qp != n_qp; ++qp)
		    Fe(js) += JxW[qp] * (parent_phi[i][qp] *
					 phi[j][qp] +
					 (parent_dphi[i][qp] *
					  face_normals[qp]) *
					 (dphi[j][qp] *
					  face_normals[qp]));
		}
	      Ke.cholesky_solve(Fe, Ue[is]);
	    }
	  for (unsigned int is = 0; is != n_side_dofs; ++is)
	    {
	      const unsigned int i = parent_side_dofs[is];
	      const unsigned int their_dof_g = parent_dof_indices[i];
	      for (unsigned int js = 0; js != n_side_dofs; ++js)
	        {
	          const unsigned int j = my_side_dofs[js];
	          const unsigned int my_dof_g = child_dof_indices[j];
		  const Real their_dof_value = Ue[is](js);
		  if (their_dof_g == my_dof_g)
		    {
		      assert(std::abs(their_dof_value-1.) < 1.e-5);
		      for (unsigned int k = 0; k != n_side_dofs; ++k)
		        assert(k == is || std::abs(Ue[k](is)) < 1.e-5);
		      continue;
		    }
		  if (std::abs(their_dof_value) < 1.e-5)
		    continue;

		  DofMap::DofConstraintRow& constraint_row =
				  constraints[my_dof_g];

		  constraint_row.insert(std::make_pair(their_dof_g,
						       static_cast<float>(their_dof_value)));
	        }
	    }
	}
#endif
}

template <unsigned int Dim, FEFamily T>
bool FE<Dim,T>::shapes_need_reinit() const
{
  return true;
}

//--------------------------------------------------------------
// Explicit instantiations
template class FE<1,CLOUGH>;  // FIXME: 1D Not yet functional!
template class FE<2,CLOUGH>;
template class FE<3,CLOUGH>;  // FIXME: 2D Not yet functional!
<|endoftext|>


<commit_before>/*
The MIT License (MIT)

Copyright (c) 2013-2015 SRS(simple-rtmp-server)

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 <srs_app_ffmpeg.hpp>

#include <stdlib.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/types.h>

// for srs-librtmp, @see https://github.com/simple-rtmp-server/srs/issues/213
#ifndef _WIN32
#include <unistd.h>
#endif

#include <vector>
using namespace std;

#include <srs_kernel_error.hpp>
#include <srs_kernel_log.hpp>
#include <srs_app_config.hpp>
#include <srs_app_utility.hpp>
#include <srs_app_process.hpp>
#include <srs_core_autofree.hpp>
#include <srs_kernel_utility.hpp>

#ifdef SRS_AUTO_FFMPEG_STUB

#define SRS_RTMP_ENCODER_COPY "copy"
#define SRS_RTMP_ENCODER_NO_VIDEO "vn"
#define SRS_RTMP_ENCODER_NO_AUDIO "an"
// only support libx264 encoder.
#define SRS_RTMP_ENCODER_VCODEC_LIBX264 "libx264"
#define SRS_RTMP_ENCODER_VCODEC_PNG "png"
// any aac encoder is ok which contains the aac,
// for example, libaacplus, aac, fdkaac
#define SRS_RTMP_ENCODER_ACODEC "aac"
#define SRS_RTMP_ENCODER_LIBAACPLUS "libaacplus"
#define SRS_RTMP_ENCODER_LIBFDKAAC "libfdk_aac"

SrsFFMPEG::SrsFFMPEG(std::string ffmpeg_bin)
{
    ffmpeg             = ffmpeg_bin;

    vbitrate         = 0;
    vfps             = 0;
    vwidth             = 0;
    vheight         = 0;
    vthreads         = 0;
    abitrate         = 0;
    asample_rate     = 0;
    achannels         = 0;
    process = new SrsProcess();
}

SrsFFMPEG::~SrsFFMPEG()
{
    stop();

    srs_freep(process);
}

void SrsFFMPEG::set_iparams(string iparams)
{
    _iparams = iparams;
}

void SrsFFMPEG::set_oformat(string format)
{
    oformat = format;
}

string SrsFFMPEG::output()
{
    return _output;
}

int SrsFFMPEG::initialize(string in, string out, string log)
{
    int ret = ERROR_SUCCESS;

    input = in;
    _output = out;
    log_file = log;

    return ret;
}

int SrsFFMPEG::initialize_transcode(SrsConfDirective* engine)
{
    int ret = ERROR_SUCCESS;

    iformat             = _srs_config->get_engine_iformat(engine);
    vfilter             = _srs_config->get_engine_vfilter(engine);
    vcodec              = _srs_config->get_engine_vcodec(engine);
    vbitrate            = _srs_config->get_engine_vbitrate(engine);
    vfps                = _srs_config->get_engine_vfps(engine);
    vwidth              = _srs_config->get_engine_vwidth(engine);
    vheight             = _srs_config->get_engine_vheight(engine);
    vthreads            = _srs_config->get_engine_vthreads(engine);
    vprofile            = _srs_config->get_engine_vprofile(engine);
    vpreset             = _srs_config->get_engine_vpreset(engine);
    copyts            	= _srs_config->get_engine_copyts(engine);
    vparams             = _srs_config->get_engine_vparams(engine);
    acodec              = _srs_config->get_engine_acodec(engine);
    abitrate            = _srs_config->get_engine_abitrate(engine);
    asample_rate        = _srs_config->get_engine_asample_rate(engine);
    achannels           = _srs_config->get_engine_achannels(engine);
    aparams             = _srs_config->get_engine_aparams(engine);
    oformat             = _srs_config->get_engine_oformat(engine);

    // ensure the size is even.
    vwidth -= vwidth % 2;
    vheight -= vheight % 2;

    if (vcodec == SRS_RTMP_ENCODER_NO_VIDEO && acodec == SRS_RTMP_ENCODER_NO_AUDIO) {
        ret = ERROR_ENCODER_VCODEC;
        srs_warn("video and audio disabled. ret=%d", ret);
        return ret;
    }

    if (vcodec != SRS_RTMP_ENCODER_COPY && vcodec != SRS_RTMP_ENCODER_NO_VIDEO && vcodec != SRS_RTMP_ENCODER_VCODEC_PNG) {
        if (vcodec != SRS_RTMP_ENCODER_VCODEC_LIBX264) {
            ret = ERROR_ENCODER_VCODEC;
            srs_error("invalid vcodec, must be %s, actual %s, ret=%d",
                SRS_RTMP_ENCODER_VCODEC_LIBX264, vcodec.c_str(), ret);
            return ret;
        }
        if (vbitrate < 0) {
            ret = ERROR_ENCODER_VBITRATE;
            srs_error("invalid vbitrate: %d, ret=%d", vbitrate, ret);
            return ret;
        }
        if (vfps < 0) {
            ret = ERROR_ENCODER_VFPS;
            srs_error("invalid vfps: %.2f, ret=%d", vfps, ret);
            return ret;
        }
        if (vwidth < 0) {
            ret = ERROR_ENCODER_VWIDTH;
            srs_error("invalid vwidth: %d, ret=%d", vwidth, ret);
            return ret;
        }
        if (vheight < 0) {
            ret = ERROR_ENCODER_VHEIGHT;
            srs_error("invalid vheight: %d, ret=%d", vheight, ret);
            return ret;
        }
        if (vthreads < 0) {
            ret = ERROR_ENCODER_VTHREADS;
            srs_error("invalid vthreads: %d, ret=%d", vthreads, ret);
            return ret;
        }
        if (vprofile.empty()) {
            ret = ERROR_ENCODER_VPROFILE;
            srs_error("invalid vprofile: %s, ret=%d", vprofile.c_str(), ret);
            return ret;
        }
        if (vpreset.empty()) {
            ret = ERROR_ENCODER_VPRESET;
            srs_error("invalid vpreset: %s, ret=%d", vpreset.c_str(), ret);
            return ret;
        }
    }

    // @see, https://github.com/simple-rtmp-server/srs/issues/145
    if (acodec == SRS_RTMP_ENCODER_LIBAACPLUS && acodec != SRS_RTMP_ENCODER_LIBFDKAAC) {
        if (abitrate != 0 && (abitrate < 16 || abitrate > 72)) {
            ret = ERROR_ENCODER_ABITRATE;
            srs_error("invalid abitrate for aac: %d, must in [16, 72], ret=%d", abitrate, ret);
            return ret;
        }
    }

    if (acodec != SRS_RTMP_ENCODER_COPY && acodec != SRS_RTMP_ENCODER_NO_AUDIO) {
        if (abitrate < 0) {
            ret = ERROR_ENCODER_ABITRATE;
            srs_error("invalid abitrate: %d, ret=%d", abitrate, ret);
            return ret;
        }
        if (asample_rate < 0) {
            ret = ERROR_ENCODER_ASAMPLE_RATE;
            srs_error("invalid sample rate: %d, ret=%d", asample_rate, ret);
            return ret;
        }
        if (achannels != 0 && achannels != 1 && achannels != 2) {
            ret = ERROR_ENCODER_ACHANNELS;
            srs_error("invalid achannels, must be 1 or 2, actual %d, ret=%d", achannels, ret);
            return ret;
        }
    }
    if (_output.empty()) {
        ret = ERROR_ENCODER_OUTPUT;
        srs_error("invalid empty output, ret=%d", ret);
        return ret;
    }

    // for not rtmp input, donot append the iformat,
    // for example, "-f flv" before "-i udp://192.168.1.252:2222"
    // @see https://github.com/simple-rtmp-server/srs/issues/290
    if (!srs_string_starts_with(input, "rtmp://")) {
        iformat = "";
    }

    return ret;
}

int SrsFFMPEG::initialize_copy()
{
    int ret = ERROR_SUCCESS;

    vcodec = SRS_RTMP_ENCODER_COPY;
    acodec = SRS_RTMP_ENCODER_COPY;

    if (_output.empty()) {
        ret = ERROR_ENCODER_OUTPUT;
        srs_error("invalid empty output, ret=%d", ret);
        return ret;
    }

    return ret;
}

int SrsFFMPEG::start()
{
    int ret = ERROR_SUCCESS;

    if (process->started()) {
        return ret;
    }

    // the argv for process.
    params.clear();

    // argv[0], set to ffmpeg bin.
    // The  execv()  and  execvp() functions ....
    // The first argument, by convention, should point to
    // the filename associated  with  the file being executed.
    params.push_back(ffmpeg);

    // input params
    if (!_iparams.empty()) {
        params.push_back(_iparams);
    }

    // input.
    if (iformat != "off" && !iformat.empty()) {
        params.push_back("-f");
        params.push_back(iformat);
    }

    params.push_back("-i");
    params.push_back(input);

    // build the filter
    if (!vfilter.empty()) {
        std::vector<std::string>::iterator it;
        for (it = vfilter.begin(); it != vfilter.end(); ++it) {
            std::string p = *it;
            if (!p.empty()) {
                params.push_back(p);
            }
        }
    }

    // video specified.
    if (vcodec != SRS_RTMP_ENCODER_NO_VIDEO) {
        params.push_back("-vcodec");
        params.push_back(vcodec);
    } else {
        params.push_back("-vn");
    }

    //nots
    if (!copyts.empty()) {
    params.push_back("-copyts");
    }

    // the codec params is disabled when copy
    if (vcodec != SRS_RTMP_ENCODER_COPY && vcodec != SRS_RTMP_ENCODER_NO_VIDEO) {
        if (vbitrate > 0) {
            params.push_back("-b:v");
            params.push_back(srs_int2str(vbitrate * 1000));
        }

        if (vfps > 0) {
            params.push_back("-r");
            params.push_back(srs_float2str(vfps));
        }

        if (vwidth > 0 && vheight > 0) {
            params.push_back("-s");
            params.push_back(srs_int2str(vwidth) + "x" + srs_int2str(vheight));
        }

        // TODO: add aspect if needed.
        if (vwidth > 0 && vheight > 0) {
            params.push_back("-aspect");
            params.push_back(srs_int2str(vwidth) + ":" + srs_int2str(vheight));
        }

        if (vthreads > 0) {
            params.push_back("-threads");
            params.push_back(srs_int2str(vthreads));
        }

        if (!vprofile.empty()) {
            params.push_back("-profile:v");
            params.push_back(vprofile);
        }

        if (!vpreset.empty()) {
            params.push_back("-preset");
            params.push_back(vpreset);
        }

        // vparams
        if (!vparams.empty()) {
            std::vector<std::string>::iterator it;
            for (it = vparams.begin(); it != vparams.end(); ++it) {
                std::string p = *it;
                if (!p.empty()) {
                    params.push_back(p);
                }
            }
        }
    }

    // audio specified.
    if (acodec != SRS_RTMP_ENCODER_NO_AUDIO) {
        params.push_back("-acodec");
        params.push_back(acodec);
    } else {
        params.push_back("-an");
    }

    // the codec params is disabled when copy
    if (acodec != SRS_RTMP_ENCODER_NO_AUDIO) {
        if (acodec != SRS_RTMP_ENCODER_COPY) {
            if (abitrate > 0) {
                params.push_back("-b:a");
                params.push_back(srs_int2str(abitrate * 1000));
            }

            if (asample_rate > 0) {
                params.push_back("-ar");
                params.push_back(srs_int2str(asample_rate));
            }

            if (achannels > 0) {
                params.push_back("-ac");
                params.push_back(srs_int2str(achannels));
            }

            // aparams
            std::vector<std::string>::iterator it;
            for (it = aparams.begin(); it != aparams.end(); ++it) {
                std::string p = *it;
                if (!p.empty()) {
                    params.push_back(p);
                }
            }
        } else {
            // for audio copy.
            for (int i = 0; i < (int)aparams.size();) {
                std::string pn = aparams[i++];

                // aparams, the adts to asc filter "-bsf:a aac_adtstoasc"
                if (pn == "-bsf:a" && i < (int)aparams.size()) {
                    std::string pv = aparams[i++];
                    if (pv == "aac_adtstoasc") {
                        params.push_back(pn);
                        params.push_back(pv);
                    }
                }
            }
        }
    }

    // output
    if (oformat != "off" && !oformat.empty()) {
        params.push_back("-f");
        params.push_back(oformat);
    }

    params.push_back("-y");
    params.push_back(_output);

    // when specified the log file.
    if (!log_file.empty()) {
        // stdout
        params.push_back("1");
        params.push_back(">");
        params.push_back(log_file);
        // stderr
        params.push_back("2");
        params.push_back(">");
        params.push_back(log_file);
    }

    // initialize the process.
    if ((ret = process->initialize(ffmpeg, params)) != ERROR_SUCCESS) {
        return ret;
    }

    return process->start();
}

int SrsFFMPEG::cycle()
{
    return process->cycle();
}

void SrsFFMPEG::stop()
{
    process->stop();
}

void SrsFFMPEG::fast_stop()
{
    process->fast_stop();
}

#endif

<commit_msg>add quotes to ffmpeg input<commit_after>/*
The MIT License (MIT)

Copyright (c) 2013-2015 SRS(simple-rtmp-server)

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 <srs_app_ffmpeg.hpp>

#include <stdlib.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/types.h>

// for srs-librtmp, @see https://github.com/simple-rtmp-server/srs/issues/213
#ifndef _WIN32
#include <unistd.h>
#endif

#include <vector>
using namespace std;

#include <srs_kernel_error.hpp>
#include <srs_kernel_log.hpp>
#include <srs_app_config.hpp>
#include <srs_app_utility.hpp>
#include <srs_app_process.hpp>
#include <srs_core_autofree.hpp>
#include <srs_kernel_utility.hpp>

#ifdef SRS_AUTO_FFMPEG_STUB

#define SRS_RTMP_ENCODER_COPY "copy"
#define SRS_RTMP_ENCODER_NO_VIDEO "vn"
#define SRS_RTMP_ENCODER_NO_AUDIO "an"
// only support libx264 encoder.
#define SRS_RTMP_ENCODER_VCODEC_LIBX264 "libx264"
#define SRS_RTMP_ENCODER_VCODEC_PNG "png"
// any aac encoder is ok which contains the aac,
// for example, libaacplus, aac, fdkaac
#define SRS_RTMP_ENCODER_ACODEC "aac"
#define SRS_RTMP_ENCODER_LIBAACPLUS "libaacplus"
#define SRS_RTMP_ENCODER_LIBFDKAAC "libfdk_aac"

SrsFFMPEG::SrsFFMPEG(std::string ffmpeg_bin)
{
    ffmpeg             = ffmpeg_bin;

    vbitrate         = 0;
    vfps             = 0;
    vwidth             = 0;
    vheight         = 0;
    vthreads         = 0;
    abitrate         = 0;
    asample_rate     = 0;
    achannels         = 0;
    process = new SrsProcess();
}

SrsFFMPEG::~SrsFFMPEG()
{
    stop();

    srs_freep(process);
}

void SrsFFMPEG::set_iparams(string iparams)
{
    _iparams = iparams;
}

void SrsFFMPEG::set_oformat(string format)
{
    oformat = format;
}

string SrsFFMPEG::output()
{
    return _output;
}

int SrsFFMPEG::initialize(string in, string out, string log)
{
    int ret = ERROR_SUCCESS;

    input = in;
    _output = out;
    log_file = log;

    return ret;
}

int SrsFFMPEG::initialize_transcode(SrsConfDirective* engine)
{
    int ret = ERROR_SUCCESS;

    iformat             = _srs_config->get_engine_iformat(engine);
    vfilter             = _srs_config->get_engine_vfilter(engine);
    vcodec              = _srs_config->get_engine_vcodec(engine);
    vbitrate            = _srs_config->get_engine_vbitrate(engine);
    vfps                = _srs_config->get_engine_vfps(engine);
    vwidth              = _srs_config->get_engine_vwidth(engine);
    vheight             = _srs_config->get_engine_vheight(engine);
    vthreads            = _srs_config->get_engine_vthreads(engine);
    vprofile            = _srs_config->get_engine_vprofile(engine);
    vpreset             = _srs_config->get_engine_vpreset(engine);
    copyts            	= _srs_config->get_engine_copyts(engine);
    vparams             = _srs_config->get_engine_vparams(engine);
    acodec              = _srs_config->get_engine_acodec(engine);
    abitrate            = _srs_config->get_engine_abitrate(engine);
    asample_rate        = _srs_config->get_engine_asample_rate(engine);
    achannels           = _srs_config->get_engine_achannels(engine);
    aparams             = _srs_config->get_engine_aparams(engine);
    oformat             = _srs_config->get_engine_oformat(engine);

    // ensure the size is even.
    vwidth -= vwidth % 2;
    vheight -= vheight % 2;

    if (vcodec == SRS_RTMP_ENCODER_NO_VIDEO && acodec == SRS_RTMP_ENCODER_NO_AUDIO) {
        ret = ERROR_ENCODER_VCODEC;
        srs_warn("video and audio disabled. ret=%d", ret);
        return ret;
    }

    if (vcodec != SRS_RTMP_ENCODER_COPY && vcodec != SRS_RTMP_ENCODER_NO_VIDEO && vcodec != SRS_RTMP_ENCODER_VCODEC_PNG) {
        if (vcodec != SRS_RTMP_ENCODER_VCODEC_LIBX264) {
            ret = ERROR_ENCODER_VCODEC;
            srs_error("invalid vcodec, must be %s, actual %s, ret=%d",
                SRS_RTMP_ENCODER_VCODEC_LIBX264, vcodec.c_str(), ret);
            return ret;
        }
        if (vbitrate < 0) {
            ret = ERROR_ENCODER_VBITRATE;
            srs_error("invalid vbitrate: %d, ret=%d", vbitrate, ret);
            return ret;
        }
        if (vfps < 0) {
            ret = ERROR_ENCODER_VFPS;
            srs_error("invalid vfps: %.2f, ret=%d", vfps, ret);
            return ret;
        }
        if (vwidth < 0) {
            ret = ERROR_ENCODER_VWIDTH;
            srs_error("invalid vwidth: %d, ret=%d", vwidth, ret);
            return ret;
        }
        if (vheight < 0) {
            ret = ERROR_ENCODER_VHEIGHT;
            srs_error("invalid vheight: %d, ret=%d", vheight, ret);
            return ret;
        }
        if (vthreads < 0) {
            ret = ERROR_ENCODER_VTHREADS;
            srs_error("invalid vthreads: %d, ret=%d", vthreads, ret);
            return ret;
        }
        if (vprofile.empty()) {
            ret = ERROR_ENCODER_VPROFILE;
            srs_error("invalid vprofile: %s, ret=%d", vprofile.c_str(), ret);
            return ret;
        }
        if (vpreset.empty()) {
            ret = ERROR_ENCODER_VPRESET;
            srs_error("invalid vpreset: %s, ret=%d", vpreset.c_str(), ret);
            return ret;
        }
    }

    // @see, https://github.com/simple-rtmp-server/srs/issues/145
    if (acodec == SRS_RTMP_ENCODER_LIBAACPLUS && acodec != SRS_RTMP_ENCODER_LIBFDKAAC) {
        if (abitrate != 0 && (abitrate < 16 || abitrate > 72)) {
            ret = ERROR_ENCODER_ABITRATE;
            srs_error("invalid abitrate for aac: %d, must in [16, 72], ret=%d", abitrate, ret);
            return ret;
        }
    }

    if (acodec != SRS_RTMP_ENCODER_COPY && acodec != SRS_RTMP_ENCODER_NO_AUDIO) {
        if (abitrate < 0) {
            ret = ERROR_ENCODER_ABITRATE;
            srs_error("invalid abitrate: %d, ret=%d", abitrate, ret);
            return ret;
        }
        if (asample_rate < 0) {
            ret = ERROR_ENCODER_ASAMPLE_RATE;
            srs_error("invalid sample rate: %d, ret=%d", asample_rate, ret);
            return ret;
        }
        if (achannels != 0 && achannels != 1 && achannels != 2) {
            ret = ERROR_ENCODER_ACHANNELS;
            srs_error("invalid achannels, must be 1 or 2, actual %d, ret=%d", achannels, ret);
            return ret;
        }
    }
    if (_output.empty()) {
        ret = ERROR_ENCODER_OUTPUT;
        srs_error("invalid empty output, ret=%d", ret);
        return ret;
    }

    // for not rtmp input, donot append the iformat,
    // for example, "-f flv" before "-i udp://192.168.1.252:2222"
    // @see https://github.com/simple-rtmp-server/srs/issues/290
    if (!srs_string_starts_with(input, "rtmp://")) {
        iformat = "";
    }

    return ret;
}

int SrsFFMPEG::initialize_copy()
{
    int ret = ERROR_SUCCESS;

    vcodec = SRS_RTMP_ENCODER_COPY;
    acodec = SRS_RTMP_ENCODER_COPY;

    if (_output.empty()) {
        ret = ERROR_ENCODER_OUTPUT;
        srs_error("invalid empty output, ret=%d", ret);
        return ret;
    }

    return ret;
}

int SrsFFMPEG::start()
{
    int ret = ERROR_SUCCESS;

    if (process->started()) {
        return ret;
    }

    // the argv for process.
    params.clear();

    // argv[0], set to ffmpeg bin.
    // The  execv()  and  execvp() functions ....
    // The first argument, by convention, should point to
    // the filename associated  with  the file being executed.
    params.push_back(ffmpeg);

    // input params
    if (!_iparams.empty()) {
        params.push_back(_iparams);
    }

    // input.
    if (iformat != "off" && !iformat.empty()) {
        params.push_back("-f");
        params.push_back(iformat);
    }

    params.push_back("-i");
    params.push_back('"'+ input + '"');

    // build the filter
    if (!vfilter.empty()) {
        std::vector<std::string>::iterator it;
        for (it = vfilter.begin(); it != vfilter.end(); ++it) {
            std::string p = *it;
            if (!p.empty()) {
                params.push_back(p);
            }
        }
    }

    // video specified.
    if (vcodec != SRS_RTMP_ENCODER_NO_VIDEO) {
        params.push_back("-vcodec");
        params.push_back(vcodec);
    } else {
        params.push_back("-vn");
    }

    //nots
    if (!copyts.empty()) {
    params.push_back("-copyts");
    }

    // the codec params is disabled when copy
    if (vcodec != SRS_RTMP_ENCODER_COPY && vcodec != SRS_RTMP_ENCODER_NO_VIDEO) {
        if (vbitrate > 0) {
            params.push_back("-b:v");
            params.push_back(srs_int2str(vbitrate * 1000));
        }

        if (vfps > 0) {
            params.push_back("-r");
            params.push_back(srs_float2str(vfps));
        }

        if (vwidth > 0 && vheight > 0) {
            params.push_back("-s");
            params.push_back(srs_int2str(vwidth) + "x" + srs_int2str(vheight));
        }

        // TODO: add aspect if needed.
        if (vwidth > 0 && vheight > 0) {
            params.push_back("-aspect");
            params.push_back(srs_int2str(vwidth) + ":" + srs_int2str(vheight));
        }

        if (vthreads > 0) {
            params.push_back("-threads");
            params.push_back(srs_int2str(vthreads));
        }

        if (!vprofile.empty()) {
            params.push_back("-profile:v");
            params.push_back(vprofile);
        }

        if (!vpreset.empty()) {
            params.push_back("-preset");
            params.push_back(vpreset);
        }

        // vparams
        if (!vparams.empty()) {
            std::vector<std::string>::iterator it;
            for (it = vparams.begin(); it != vparams.end(); ++it) {
                std::string p = *it;
                if (!p.empty()) {
                    params.push_back(p);
                }
            }
        }
    }

    // audio specified.
    if (acodec != SRS_RTMP_ENCODER_NO_AUDIO) {
        params.push_back("-acodec");
        params.push_back(acodec);
    } else {
        params.push_back("-an");
    }

    // the codec params is disabled when copy
    if (acodec != SRS_RTMP_ENCODER_NO_AUDIO) {
        if (acodec != SRS_RTMP_ENCODER_COPY) {
            if (abitrate > 0) {
                params.push_back("-b:a");
                params.push_back(srs_int2str(abitrate * 1000));
            }

            if (asample_rate > 0) {
                params.push_back("-ar");
                params.push_back(srs_int2str(asample_rate));
            }

            if (achannels > 0) {
                params.push_back("-ac");
                params.push_back(srs_int2str(achannels));
            }

            // aparams
            std::vector<std::string>::iterator it;
            for (it = aparams.begin(); it != aparams.end(); ++it) {
                std::string p = *it;
                if (!p.empty()) {
                    params.push_back(p);
                }
            }
        } else {
            // for audio copy.
            for (int i = 0; i < (int)aparams.size();) {
                std::string pn = aparams[i++];

                // aparams, the adts to asc filter "-bsf:a aac_adtstoasc"
                if (pn == "-bsf:a" && i < (int)aparams.size()) {
                    std::string pv = aparams[i++];
                    if (pv == "aac_adtstoasc") {
                        params.push_back(pn);
                        params.push_back(pv);
                    }
                }
            }
        }
    }

    // output
    if (oformat != "off" && !oformat.empty()) {
        params.push_back("-f");
        params.push_back(oformat);
    }

    params.push_back("-y");
    params.push_back(_output);

    // when specified the log file.
    if (!log_file.empty()) {
        // stdout
        params.push_back("1");
        params.push_back(">");
        params.push_back(log_file);
        // stderr
        params.push_back("2");
        params.push_back(">");
        params.push_back(log_file);
    }

    // initialize the process.
    if ((ret = process->initialize(ffmpeg, params)) != ERROR_SUCCESS) {
        return ret;
    }

    return process->start();
}

int SrsFFMPEG::cycle()
{
    return process->cycle();
}

void SrsFFMPEG::stop()
{
    process->stop();
}

void SrsFFMPEG::fast_stop()
{
    process->fast_stop();
}

#endif

<|endoftext|>