<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: NeonPropFindRequest.cxx,v $
 *
 *  $Revision: 1.15 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-20 05:36:43 $
 *
 *  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 _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif

#ifndef _NEONTYPES_HXX_
#include "NeonTypes.hxx"
#endif
#ifndef _DAVEXCEPTION_HXX_
#include "DAVException.hxx"
#endif
#ifndef _DAVPROPERTIES_HXX_
#include "DAVProperties.hxx"
#endif
#ifndef _NEONPROPFINDREQUEST_HXX_
#include "NeonPropFindRequest.hxx"
#endif
#ifndef _LINKSEQUENCE_HXX_
#include "LinkSequence.hxx"
#endif
#ifndef _LOCKSEQUENCE_HXX_
#include "LockSequence.hxx"
#endif
#ifndef _LOCKENTRYSEQUENCE_HXX_
#include "LockEntrySequence.hxx"
#endif
#ifndef _UCBDEADPROPERTYVALUE_HXX_
#include "UCBDeadPropertyValue.hxx"
#endif

using namespace rtl;
using namespace com::sun::star::beans;
using namespace com::sun::star::uno;
using namespace com::sun::star::ucb;
using namespace std;
using namespace webdav_ucp;

// -------------------------------------------------------------------
extern "C" int NPFR_propfind_iter( void* userdata,
                                   const NeonPropName* pname,
                                   const char* value,
                                   const HttpStatus* status )
{
    /*
        HTTP Response Status Classes:

          - 1: Informational - Request received, continuing process

          - 2: Success - The action was successfully received,
          understood, and accepted

        - 3: Redirection - Further action must be taken in order to
          complete the request

        - 4: Client Error - The request contains bad syntax or cannot
          be fulfilled

        - 5: Server Error - The server failed to fulfill an apparently
          valid request
    */

    if ( status->klass > 2 )
        return 0; // Error getting this property. Go on.

    // Create & set the PropertyValue
    PropertyValue thePropertyValue;
    thePropertyValue.Handle = -1;
    thePropertyValue.State = PropertyState_DIRECT_VALUE;

    DAVProperties::createUCBPropName( pname->nspace,
                                        pname->name,
                                        thePropertyValue.Name );
    bool bHasValue = false;
    if ( DAVProperties::isUCBDeadProperty( *pname ) )
    {
        // DAV dead property added by WebDAV UCP?
        if ( UCBDeadPropertyValue::createFromXML(
                                        value, thePropertyValue.Value ) )
            OSL_ENSURE( thePropertyValue.Value.hasValue(),
                        "NeonPropFindRequest::propfind_iter - No value!" );
            bHasValue = true;
    }

    if ( !bHasValue )
    {
        if ( rtl_str_compareIgnoreAsciiCase(
                                    pname->name, "resourcetype" ) == 0 )
        {
            OString aValue( value );
            aValue = aValue.trim(); // #107358# remove leading/trailing spaces
            if ( aValue.getLength() )
            {
                aValue = aValue.toAsciiLowerCase();
                if ( aValue.compareTo(
                        RTL_CONSTASCII_STRINGPARAM( "<collection" ) ) == 0 )
                {
                    thePropertyValue.Value
                        <<= OUString::createFromAscii( "collection" );
                }
            }

            if ( !thePropertyValue.Value.hasValue() )
            {
                // Take over the value exactly as supplied by the server.
                thePropertyValue.Value <<= OUString::createFromAscii( value );
            }
        }
        else if ( rtl_str_compareIgnoreAsciiCase(
                                    pname->name, "supportedlock" ) == 0 )
        {
            Sequence< LockEntry > aEntries;
            LockEntrySequence::createFromXML( value, aEntries );
            thePropertyValue.Value <<= aEntries;
        }
        else if ( rtl_str_compareIgnoreAsciiCase(
                                    pname->name, "lockdiscovery" ) == 0 )
        {
            Sequence< Lock > aLocks;
            LockSequence::createFromXML( value, aLocks );
            thePropertyValue.Value <<= aLocks;
        }
        else if ( rtl_str_compareIgnoreAsciiCase( pname->name, "source" ) == 0 )
        {
            Sequence< Link > aLinks;
            LinkSequence::createFromXML( value, aLinks );
            thePropertyValue.Value <<= aLinks;
        }
        else
        {
            thePropertyValue.Value
                <<= OStringToOUString( value, RTL_TEXTENCODING_UTF8 );
        }
    }

    // Add the newly created PropertyValue
    DAVResource* theResource = static_cast< DAVResource * >( userdata );
    theResource->properties.push_back( thePropertyValue );

    return 0; // Go on.
}

// -------------------------------------------------------------------
extern "C" void NPFR_propfind_results( void* userdata,
                                       const char* href,
                                       const NeonPropFindResultSet* set )
{
    // @@@ href is not the uri! DAVResource ctor wants uri!

    DAVResource theResource(
                        OStringToOUString( href, RTL_TEXTENCODING_UTF8 ) );

    ne_propset_iterate( set, NPFR_propfind_iter, &theResource );

    // Add entry to resources list.
    vector< DAVResource > * theResources
        = static_cast< vector< DAVResource > * >( userdata );
    theResources->push_back( theResource );
}

// -------------------------------------------------------------------
extern "C" int NPFR_propnames_iter( void* userdata,
                                    const NeonPropName* pname,
                                    const char* /*value*/,
                                    const HttpStatus* /*status*/ )
{
    OUString aFullName;
    DAVProperties::createUCBPropName( pname->nspace,
                                      pname->name,
                                      aFullName );

    DAVResourceInfo* theResource = static_cast< DAVResourceInfo * >( userdata );
    theResource->properties.push_back( aFullName );
    return 0;
}

// -------------------------------------------------------------------
extern "C" void NPFR_propnames_results( void* userdata,
                                        const char* href,
                                        const NeonPropFindResultSet* results )
{
    // @@@ href is not the uri! DAVResourceInfo ctor wants uri!

    // Create entry for the resource.
    DAVResourceInfo theResource(
                        OStringToOUString( href, RTL_TEXTENCODING_UTF8 ) );
    // Fill entry.
    ne_propset_iterate( results, NPFR_propnames_iter, &theResource );

    // Add entry to resources list.
    vector< DAVResourceInfo > * theResources
        = static_cast< vector< DAVResourceInfo > * >( userdata );
    theResources->push_back( theResource );
}

// -------------------------------------------------------------------
// Constructor
// -------------------------------------------------------------------

NeonPropFindRequest::NeonPropFindRequest( HttpSession* inSession,
                                          const char* inPath,
                                          const Depth inDepth,
                                          const vector< OUString >& inPropNames,
                                          vector< DAVResource >& ioResources,
                                          int & nError )
{
    // Generate the list of properties we're looking for
    int thePropCount = inPropNames.size();
    if ( thePropCount > 0 )
    {
        NeonPropName* thePropNames = new NeonPropName[ thePropCount + 1 ];
        int theIndex;

        for ( theIndex = 0; theIndex < thePropCount; theIndex ++ )
        {
            // Split fullname into namespace and name!
            DAVProperties::createNeonPropName(
                             inPropNames[ theIndex ], thePropNames[ theIndex ] );
        }
        thePropNames[ theIndex ].nspace = NULL;
        thePropNames[ theIndex ].name   = NULL;

        nError = ne_simple_propfind( inSession,
                                     inPath,
                                     inDepth,
                                     thePropNames,
                                     NPFR_propfind_results,
                                     &ioResources );

        for ( theIndex = 0; theIndex < thePropCount; theIndex ++ )
            free( (void *)thePropNames[ theIndex ].name );

        delete [] thePropNames;
    }
    else
    {
        // ALLPROP
        nError = ne_simple_propfind( inSession,
                                     inPath,
                                     inDepth,
                                     NULL, // 0 == allprop
                                     NPFR_propfind_results,
                                     &ioResources );
    }

    // #87585# - Sometimes neon lies (because some servers lie).
    if ( ( nError == NE_OK ) && ioResources.empty() )
        nError = NE_ERROR;
}

// -------------------------------------------------------------------
// Constructor
// - obtains property names
// -------------------------------------------------------------------

NeonPropFindRequest::NeonPropFindRequest(
                            HttpSession* inSession,
                            const char* inPath,
                                const Depth inDepth,
                            std::vector< DAVResourceInfo > & ioResInfo,
                            int & nError )
{
    nError = ne_propnames( inSession,
                           inPath,
                           inDepth,
                           NPFR_propnames_results,
                           &ioResInfo );

    // #87585# - Sometimes neon lies (because some servers lie).
    if ( ( nError == NE_OK ) && ioResInfo.empty() )
        nError = NE_ERROR;
}

// -------------------------------------------------------------------
// Destructor
// -------------------------------------------------------------------
NeonPropFindRequest::~NeonPropFindRequest( )
{
}
<commit_msg>INTEGRATION: CWS configure18 (1.15.6); FILE MERGED 2006/07/13 15:18:19 rene 1.15.6.1: #i64798# system neon 0.26.x support, by geki<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: NeonPropFindRequest.cxx,v $
 *
 *  $Revision: 1.16 $
 *
 *  last change: $Author: kz $ $Date: 2006-07-19 09:35:25 $
 *
 *  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 _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif

#ifndef _NEONTYPES_HXX_
#include "NeonTypes.hxx"
#endif
#ifndef _DAVEXCEPTION_HXX_
#include "DAVException.hxx"
#endif
#ifndef _DAVPROPERTIES_HXX_
#include "DAVProperties.hxx"
#endif
#ifndef _NEONPROPFINDREQUEST_HXX_
#include "NeonPropFindRequest.hxx"
#endif
#ifndef _LINKSEQUENCE_HXX_
#include "LinkSequence.hxx"
#endif
#ifndef _LOCKSEQUENCE_HXX_
#include "LockSequence.hxx"
#endif
#ifndef _LOCKENTRYSEQUENCE_HXX_
#include "LockEntrySequence.hxx"
#endif
#ifndef _UCBDEADPROPERTYVALUE_HXX_
#include "UCBDeadPropertyValue.hxx"
#endif

using namespace rtl;
using namespace com::sun::star::beans;
using namespace com::sun::star::uno;
using namespace com::sun::star::ucb;
using namespace std;
using namespace webdav_ucp;

// -------------------------------------------------------------------
extern "C" int NPFR_propfind_iter( void* userdata,
                                   const NeonPropName* pname,
                                   const char* value,
                                   const HttpStatus* status )
{
    /*
        HTTP Response Status Classes:

          - 1: Informational - Request received, continuing process

          - 2: Success - The action was successfully received,
          understood, and accepted

        - 3: Redirection - Further action must be taken in order to
          complete the request

        - 4: Client Error - The request contains bad syntax or cannot
          be fulfilled

        - 5: Server Error - The server failed to fulfill an apparently
          valid request
    */

    if ( status->klass > 2 )
        return 0; // Error getting this property. Go on.

    // Create & set the PropertyValue
    PropertyValue thePropertyValue;
    thePropertyValue.Handle = -1;
    thePropertyValue.State = PropertyState_DIRECT_VALUE;

    DAVProperties::createUCBPropName( pname->nspace,
                                        pname->name,
                                        thePropertyValue.Name );
    bool bHasValue = false;
    if ( DAVProperties::isUCBDeadProperty( *pname ) )
    {
        // DAV dead property added by WebDAV UCP?
        if ( UCBDeadPropertyValue::createFromXML(
                                        value, thePropertyValue.Value ) )
            OSL_ENSURE( thePropertyValue.Value.hasValue(),
                        "NeonPropFindRequest::propfind_iter - No value!" );
            bHasValue = true;
    }

    if ( !bHasValue )
    {
        if ( rtl_str_compareIgnoreAsciiCase(
                                    pname->name, "resourcetype" ) == 0 )
        {
            OString aValue( value );
            aValue = aValue.trim(); // #107358# remove leading/trailing spaces
            if ( aValue.getLength() )
            {
                aValue = aValue.toAsciiLowerCase();
                if ( aValue.compareTo(
                        RTL_CONSTASCII_STRINGPARAM( "<collection" ) ) == 0 )
                {
                    thePropertyValue.Value
                        <<= OUString::createFromAscii( "collection" );
                }
            }

            if ( !thePropertyValue.Value.hasValue() )
            {
                // Take over the value exactly as supplied by the server.
                thePropertyValue.Value <<= OUString::createFromAscii( value );
            }
        }
        else if ( rtl_str_compareIgnoreAsciiCase(
                                    pname->name, "supportedlock" ) == 0 )
        {
            Sequence< LockEntry > aEntries;
            LockEntrySequence::createFromXML( value, aEntries );
            thePropertyValue.Value <<= aEntries;
        }
        else if ( rtl_str_compareIgnoreAsciiCase(
                                    pname->name, "lockdiscovery" ) == 0 )
        {
            Sequence< Lock > aLocks;
            LockSequence::createFromXML( value, aLocks );
            thePropertyValue.Value <<= aLocks;
        }
        else if ( rtl_str_compareIgnoreAsciiCase( pname->name, "source" ) == 0 )
        {
            Sequence< Link > aLinks;
            LinkSequence::createFromXML( value, aLinks );
            thePropertyValue.Value <<= aLinks;
        }
        else
        {
            thePropertyValue.Value
                <<= OStringToOUString( value, RTL_TEXTENCODING_UTF8 );
        }
    }

    // Add the newly created PropertyValue
    DAVResource* theResource = static_cast< DAVResource * >( userdata );
    theResource->properties.push_back( thePropertyValue );

    return 0; // Go on.
}

// -------------------------------------------------------------------
extern "C" void NPFR_propfind_results( void* userdata,
#if NEON_VERSION >= 0260
                                       const ne_uri* href_uri,
#else
                                       const char* href,
#endif
                                       const NeonPropFindResultSet* set )
{
    // @@@ href is not the uri! DAVResource ctor wants uri!

#if NEON_VERSION >= 0260
    // href should be free'd? says header ...
    char* href = ne_uri_unparse(href_uri);
#endif
    DAVResource theResource(
                        OStringToOUString( href, RTL_TEXTENCODING_UTF8 ) );

    ne_propset_iterate( set, NPFR_propfind_iter, &theResource );

    // Add entry to resources list.
    vector< DAVResource > * theResources
        = static_cast< vector< DAVResource > * >( userdata );
    theResources->push_back( theResource );
}

// -------------------------------------------------------------------
extern "C" int NPFR_propnames_iter( void* userdata,
                                    const NeonPropName* pname,
                                    const char* /*value*/,
                                    const HttpStatus* /*status*/ )
{
    OUString aFullName;
    DAVProperties::createUCBPropName( pname->nspace,
                                      pname->name,
                                      aFullName );

    DAVResourceInfo* theResource = static_cast< DAVResourceInfo * >( userdata );
    theResource->properties.push_back( aFullName );
    return 0;
}

// -------------------------------------------------------------------
extern "C" void NPFR_propnames_results( void* userdata,
#if NEON_VERSION >= 0260
                                        const ne_uri* href_uri,
#else
                                        const char* href,
#endif
                                        const NeonPropFindResultSet* results )
{
    // @@@ href is not the uri! DAVResourceInfo ctor wants uri!

#if NEON_VERSION >= 0260
    // href should be free'd? says header ...
    char* href = ne_uri_unparse(href_uri);
#endif
    // Create entry for the resource.
    DAVResourceInfo theResource(
                        OStringToOUString( href, RTL_TEXTENCODING_UTF8 ) );
    // Fill entry.
    ne_propset_iterate( results, NPFR_propnames_iter, &theResource );

    // Add entry to resources list.
    vector< DAVResourceInfo > * theResources
        = static_cast< vector< DAVResourceInfo > * >( userdata );
    theResources->push_back( theResource );
}

// -------------------------------------------------------------------
// Constructor
// -------------------------------------------------------------------

NeonPropFindRequest::NeonPropFindRequest( HttpSession* inSession,
                                          const char* inPath,
                                          const Depth inDepth,
                                          const vector< OUString >& inPropNames,
                                          vector< DAVResource >& ioResources,
                                          int & nError )
{
    // Generate the list of properties we're looking for
    int thePropCount = inPropNames.size();
    if ( thePropCount > 0 )
    {
        NeonPropName* thePropNames = new NeonPropName[ thePropCount + 1 ];
        int theIndex;

        for ( theIndex = 0; theIndex < thePropCount; theIndex ++ )
        {
            // Split fullname into namespace and name!
            DAVProperties::createNeonPropName(
                             inPropNames[ theIndex ], thePropNames[ theIndex ] );
        }
        thePropNames[ theIndex ].nspace = NULL;
        thePropNames[ theIndex ].name   = NULL;

        nError = ne_simple_propfind( inSession,
                                     inPath,
                                     inDepth,
                                     thePropNames,
                                     NPFR_propfind_results,
                                     &ioResources );

        for ( theIndex = 0; theIndex < thePropCount; theIndex ++ )
            free( (void *)thePropNames[ theIndex ].name );

        delete [] thePropNames;
    }
    else
    {
        // ALLPROP
        nError = ne_simple_propfind( inSession,
                                     inPath,
                                     inDepth,
                                     NULL, // 0 == allprop
                                     NPFR_propfind_results,
                                     &ioResources );
    }

    // #87585# - Sometimes neon lies (because some servers lie).
    if ( ( nError == NE_OK ) && ioResources.empty() )
        nError = NE_ERROR;
}

// -------------------------------------------------------------------
// Constructor
// - obtains property names
// -------------------------------------------------------------------

NeonPropFindRequest::NeonPropFindRequest(
                            HttpSession* inSession,
                            const char* inPath,
                                const Depth inDepth,
                            std::vector< DAVResourceInfo > & ioResInfo,
                            int & nError )
{
    nError = ne_propnames( inSession,
                           inPath,
                           inDepth,
                           NPFR_propnames_results,
                           &ioResInfo );

    // #87585# - Sometimes neon lies (because some servers lie).
    if ( ( nError == NE_OK ) && ioResInfo.empty() )
        nError = NE_ERROR;
}

// -------------------------------------------------------------------
// Destructor
// -------------------------------------------------------------------
NeonPropFindRequest::~NeonPropFindRequest( )
{
}
<|endoftext|>


<commit_before>//===-- PathMappingList.cpp -------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// C Includes
#include <limits.h>
#include <string.h>

// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Error.h"
#include "lldb/Core/Stream.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Target/PathMappingList.h"

using namespace lldb;
using namespace lldb_private;

//----------------------------------------------------------------------
// PathMappingList constructor
//----------------------------------------------------------------------
PathMappingList::PathMappingList () :
    m_pairs (),
    m_callback (NULL),
    m_callback_baton (NULL)
{
}

PathMappingList::PathMappingList
(
    ChangedCallback callback,
    void *callback_baton
) :
    m_pairs (),
    m_callback (callback),
    m_callback_baton (callback_baton)
{
}

PathMappingList::PathMappingList (const PathMappingList &rhs) :
    m_pairs (rhs.m_pairs),
    m_callback (NULL),
    m_callback_baton (NULL)
{

}

const PathMappingList &
PathMappingList::operator =(const PathMappingList &rhs)
{
    if (this != &rhs)
    {
        m_pairs = rhs.m_pairs;
        m_callback = NULL;
        m_callback_baton = NULL;
    }
    return *this;
}

//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
PathMappingList::~PathMappingList ()
{
}

void
PathMappingList::Append (const ConstString &path,
                         const ConstString &replacement,
                         bool notify)
{
    m_pairs.push_back(pair(path, replacement));
    if (notify && m_callback)
        m_callback (*this, m_callback_baton);
}

void
PathMappingList::Append (const PathMappingList &rhs, bool notify)
{
    if (!rhs.m_pairs.empty())
    {
        const_iterator pos, end = rhs.m_pairs.end();
        for (pos = rhs.m_pairs.begin(); pos != end; ++pos)
            m_pairs.push_back(*pos);
        if (notify && m_callback)
            m_callback (*this, m_callback_baton);
    }
}

void
PathMappingList::Insert (const ConstString &path,
                         const ConstString &replacement,
                         uint32_t index,
                         bool notify)
{
    iterator insert_iter;
    if (index >= m_pairs.size())
        insert_iter = m_pairs.end();
    else
        insert_iter = m_pairs.begin() + index;
    m_pairs.insert(insert_iter, pair(path, replacement));
    if (notify && m_callback)
        m_callback (*this, m_callback_baton);
}

bool
PathMappingList::Replace (const ConstString &path,
                          const ConstString &replacement,
                          uint32_t index,
                          bool notify)
{
    iterator insert_iter;
    if (index >= m_pairs.size())
        return false;
    m_pairs[index] = pair(path, replacement);
    if (notify && m_callback)
        m_callback (*this, m_callback_baton);
    return true;
}

bool
PathMappingList::Remove (off_t index, bool notify)
{
    if (index >= m_pairs.size())
        return false;

    iterator iter = m_pairs.begin() + index;
    m_pairs.erase(iter);
    if (notify && m_callback)
        m_callback (*this, m_callback_baton);
    return true;
}

// For clients which do not need the pair index dumped, pass a pair_index >= 0
// to only dump the indicated pair.
void
PathMappingList::Dump (Stream *s, int pair_index)
{
    unsigned int numPairs = m_pairs.size();

    if (pair_index < 0)
    {
        unsigned int index;
        for (index = 0; index < numPairs; ++index)
            s->Printf("[%d] \"%s\" -> \"%s\"\n",
                      index, m_pairs[index].first.GetCString(), m_pairs[index].second.GetCString());
    }
    else
    {
        if (pair_index < numPairs)
            s->Printf("%s -> %s",
                      m_pairs[pair_index].first.GetCString(), m_pairs[pair_index].second.GetCString());
    }
}

void
PathMappingList::Clear (bool notify)
{
    m_pairs.clear();
    if (notify && m_callback)
        m_callback (*this, m_callback_baton);
}

bool
PathMappingList::RemapPath (const ConstString &path, ConstString &new_path) const
{
    const_iterator pos, end = m_pairs.end();
    for (pos = m_pairs.begin(); pos != end; ++pos)
    {
        const size_t prefixLen = pos->first.GetLength();

        if (::strncmp (pos->first.GetCString(), path.GetCString(), prefixLen) == 0)
        {
            std::string new_path_str (pos->second.GetCString());
            new_path_str.append(path.GetCString() + prefixLen);
            new_path.SetCString(new_path_str.c_str());
            return true;
        }
    }
    return false;
}

bool
PathMappingList::RemapPath (const char *path, std::string &new_path) const
{
    if (m_pairs.empty() || path == NULL || path[0] == '\0')
        return false;

    const_iterator pos, end = m_pairs.end();
    for (pos = m_pairs.begin(); pos != end; ++pos)
    {
        const size_t prefix_len = pos->first.GetLength();

        if (::strncmp (pos->first.GetCString(), path, prefix_len) == 0)
        {
            new_path = pos->second.GetCString();
            new_path.append(path + prefix_len);
            return true;
        }
    }
    return false;
}

bool
PathMappingList::FindFile (const FileSpec &orig_spec, FileSpec &new_spec) const
{
    if (!m_pairs.empty())
    {
        char orig_path[PATH_MAX];
        char new_path[PATH_MAX];
        const size_t orig_path_len = orig_spec.GetPath (orig_path, sizeof(orig_path));
        if (orig_path_len > 0)
        {
            const_iterator pos, end = m_pairs.end();
            for (pos = m_pairs.begin(); pos != end; ++pos)
            {
                const size_t prefix_len = pos->first.GetLength();

                if (orig_path_len >= prefix_len)
                {
                    if (::strncmp (pos->first.GetCString(), orig_path, prefix_len) == 0)
                    {
                        const size_t new_path_len = snprintf(new_path, sizeof(new_path), "%s/%s", pos->second.GetCString(), orig_path + prefix_len);
                        if (new_path_len < sizeof(new_path))
                        {
                            new_spec.SetFile (new_path, true);
                            if (new_spec.Exists())
                                return true;
                        }
                    }
                }
            }
        }
    }
    new_spec.Clear();
    return false;
}

bool
PathMappingList::Replace (const ConstString &path, const ConstString &new_path, bool notify)
{
    uint32_t idx = FindIndexForPath (path);
    if (idx < m_pairs.size())
    {
        m_pairs[idx].second = new_path;
        if (notify && m_callback)
            m_callback (*this, m_callback_baton);
        return true;
    }
    return false;
}

bool
PathMappingList::Remove (const ConstString &path, bool notify)
{
    iterator pos = FindIteratorForPath (path);
    if (pos != m_pairs.end())
    {
        m_pairs.erase (pos);
        if (notify && m_callback)
            m_callback (*this, m_callback_baton);
        return true;
    }
    return false;
}

PathMappingList::const_iterator
PathMappingList::FindIteratorForPath (const ConstString &path) const
{
    const_iterator pos;
    const_iterator begin = m_pairs.begin();
    const_iterator end = m_pairs.end();

    for (pos = begin; pos != end; ++pos)
    {
        if (pos->first == path)
            break;
    }
    return pos;
}

PathMappingList::iterator
PathMappingList::FindIteratorForPath (const ConstString &path)
{
    iterator pos;
    iterator begin = m_pairs.begin();
    iterator end = m_pairs.end();

    for (pos = begin; pos != end; ++pos)
    {
        if (pos->first == path)
            break;
    }
    return pos;
}

bool
PathMappingList::GetPathsAtIndex (uint32_t idx, ConstString &path, ConstString &new_path) const
{
    if (idx < m_pairs.size())
    {
        path = m_pairs[idx].first;
        new_path = m_pairs[idx].second;
        return true;
    }
    return false;
}

uint32_t
PathMappingList::FindIndexForPath (const ConstString &path) const
{
    const_iterator pos;
    const_iterator begin = m_pairs.begin();
    const_iterator end = m_pairs.end();

    for (pos = begin; pos != end; ++pos)
    {
        if (pos->first == path)
            return std::distance (begin, pos);
    }
    return UINT32_MAX;
}

<commit_msg>Fixed a bug in the path remapper that caused a crash if the path to be remaped was NULL.<commit_after>//===-- PathMappingList.cpp -------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// C Includes
#include <limits.h>
#include <string.h>

// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Error.h"
#include "lldb/Core/Stream.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Target/PathMappingList.h"

using namespace lldb;
using namespace lldb_private;

//----------------------------------------------------------------------
// PathMappingList constructor
//----------------------------------------------------------------------
PathMappingList::PathMappingList () :
    m_pairs (),
    m_callback (NULL),
    m_callback_baton (NULL)
{
}

PathMappingList::PathMappingList
(
    ChangedCallback callback,
    void *callback_baton
) :
    m_pairs (),
    m_callback (callback),
    m_callback_baton (callback_baton)
{
}

PathMappingList::PathMappingList (const PathMappingList &rhs) :
    m_pairs (rhs.m_pairs),
    m_callback (NULL),
    m_callback_baton (NULL)
{

}

const PathMappingList &
PathMappingList::operator =(const PathMappingList &rhs)
{
    if (this != &rhs)
    {
        m_pairs = rhs.m_pairs;
        m_callback = NULL;
        m_callback_baton = NULL;
    }
    return *this;
}

//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
PathMappingList::~PathMappingList ()
{
}

void
PathMappingList::Append (const ConstString &path,
                         const ConstString &replacement,
                         bool notify)
{
    m_pairs.push_back(pair(path, replacement));
    if (notify && m_callback)
        m_callback (*this, m_callback_baton);
}

void
PathMappingList::Append (const PathMappingList &rhs, bool notify)
{
    if (!rhs.m_pairs.empty())
    {
        const_iterator pos, end = rhs.m_pairs.end();
        for (pos = rhs.m_pairs.begin(); pos != end; ++pos)
            m_pairs.push_back(*pos);
        if (notify && m_callback)
            m_callback (*this, m_callback_baton);
    }
}

void
PathMappingList::Insert (const ConstString &path,
                         const ConstString &replacement,
                         uint32_t index,
                         bool notify)
{
    iterator insert_iter;
    if (index >= m_pairs.size())
        insert_iter = m_pairs.end();
    else
        insert_iter = m_pairs.begin() + index;
    m_pairs.insert(insert_iter, pair(path, replacement));
    if (notify && m_callback)
        m_callback (*this, m_callback_baton);
}

bool
PathMappingList::Replace (const ConstString &path,
                          const ConstString &replacement,
                          uint32_t index,
                          bool notify)
{
    iterator insert_iter;
    if (index >= m_pairs.size())
        return false;
    m_pairs[index] = pair(path, replacement);
    if (notify && m_callback)
        m_callback (*this, m_callback_baton);
    return true;
}

bool
PathMappingList::Remove (off_t index, bool notify)
{
    if (index >= m_pairs.size())
        return false;

    iterator iter = m_pairs.begin() + index;
    m_pairs.erase(iter);
    if (notify && m_callback)
        m_callback (*this, m_callback_baton);
    return true;
}

// For clients which do not need the pair index dumped, pass a pair_index >= 0
// to only dump the indicated pair.
void
PathMappingList::Dump (Stream *s, int pair_index)
{
    unsigned int numPairs = m_pairs.size();

    if (pair_index < 0)
    {
        unsigned int index;
        for (index = 0; index < numPairs; ++index)
            s->Printf("[%d] \"%s\" -> \"%s\"\n",
                      index, m_pairs[index].first.GetCString(), m_pairs[index].second.GetCString());
    }
    else
    {
        if (pair_index < numPairs)
            s->Printf("%s -> %s",
                      m_pairs[pair_index].first.GetCString(), m_pairs[pair_index].second.GetCString());
    }
}

void
PathMappingList::Clear (bool notify)
{
    m_pairs.clear();
    if (notify && m_callback)
        m_callback (*this, m_callback_baton);
}

bool
PathMappingList::RemapPath (const ConstString &path, ConstString &new_path) const
{
    const char *path_cstr = path.GetCString();

    if (!path_cstr)
        return false;

    const_iterator pos, end = m_pairs.end();
    for (pos = m_pairs.begin(); pos != end; ++pos)
    {
        const size_t prefixLen = pos->first.GetLength();

        if (::strncmp (pos->first.GetCString(), path_cstr, prefixLen) == 0)
        {
            std::string new_path_str (pos->second.GetCString());
            new_path_str.append(path.GetCString() + prefixLen);
            new_path.SetCString(new_path_str.c_str());
            return true;
        }
    }
    return false;
}

bool
PathMappingList::RemapPath (const char *path, std::string &new_path) const
{
    if (m_pairs.empty() || path == NULL || path[0] == '\0')
        return false;

    const_iterator pos, end = m_pairs.end();
    for (pos = m_pairs.begin(); pos != end; ++pos)
    {
        const size_t prefix_len = pos->first.GetLength();

        if (::strncmp (pos->first.GetCString(), path, prefix_len) == 0)
        {
            new_path = pos->second.GetCString();
            new_path.append(path + prefix_len);
            return true;
        }
    }
    return false;
}

bool
PathMappingList::FindFile (const FileSpec &orig_spec, FileSpec &new_spec) const
{
    if (!m_pairs.empty())
    {
        char orig_path[PATH_MAX];
        char new_path[PATH_MAX];
        const size_t orig_path_len = orig_spec.GetPath (orig_path, sizeof(orig_path));
        if (orig_path_len > 0)
        {
            const_iterator pos, end = m_pairs.end();
            for (pos = m_pairs.begin(); pos != end; ++pos)
            {
                const size_t prefix_len = pos->first.GetLength();

                if (orig_path_len >= prefix_len)
                {
                    if (::strncmp (pos->first.GetCString(), orig_path, prefix_len) == 0)
                    {
                        const size_t new_path_len = snprintf(new_path, sizeof(new_path), "%s/%s", pos->second.GetCString(), orig_path + prefix_len);
                        if (new_path_len < sizeof(new_path))
                        {
                            new_spec.SetFile (new_path, true);
                            if (new_spec.Exists())
                                return true;
                        }
                    }
                }
            }
        }
    }
    new_spec.Clear();
    return false;
}

bool
PathMappingList::Replace (const ConstString &path, const ConstString &new_path, bool notify)
{
    uint32_t idx = FindIndexForPath (path);
    if (idx < m_pairs.size())
    {
        m_pairs[idx].second = new_path;
        if (notify && m_callback)
            m_callback (*this, m_callback_baton);
        return true;
    }
    return false;
}

bool
PathMappingList::Remove (const ConstString &path, bool notify)
{
    iterator pos = FindIteratorForPath (path);
    if (pos != m_pairs.end())
    {
        m_pairs.erase (pos);
        if (notify && m_callback)
            m_callback (*this, m_callback_baton);
        return true;
    }
    return false;
}

PathMappingList::const_iterator
PathMappingList::FindIteratorForPath (const ConstString &path) const
{
    const_iterator pos;
    const_iterator begin = m_pairs.begin();
    const_iterator end = m_pairs.end();

    for (pos = begin; pos != end; ++pos)
    {
        if (pos->first == path)
            break;
    }
    return pos;
}

PathMappingList::iterator
PathMappingList::FindIteratorForPath (const ConstString &path)
{
    iterator pos;
    iterator begin = m_pairs.begin();
    iterator end = m_pairs.end();

    for (pos = begin; pos != end; ++pos)
    {
        if (pos->first == path)
            break;
    }
    return pos;
}

bool
PathMappingList::GetPathsAtIndex (uint32_t idx, ConstString &path, ConstString &new_path) const
{
    if (idx < m_pairs.size())
    {
        path = m_pairs[idx].first;
        new_path = m_pairs[idx].second;
        return true;
    }
    return false;
}

uint32_t
PathMappingList::FindIndexForPath (const ConstString &path) const
{
    const_iterator pos;
    const_iterator begin = m_pairs.begin();
    const_iterator end = m_pairs.end();

    for (pos = begin; pos != end; ++pos)
    {
        if (pos->first == path)
            return std::distance (begin, pos);
    }
    return UINT32_MAX;
}

<|endoftext|>


<commit_before>/**************************************************************************
 * Copyright(c) 1998-2000, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

 //////////////////////////////////////////////////////////////////////////////
//                                                                           //
//  Forward Multiplicity Detector based on Silicon plates                    //
//  This class contains the procedures simulation ADC  signal for            //
//  the Forward Multiplicity detector  : hits -> digits                      //
//  ADC signal consists                                                      //
//   - number of detector;                                                   //
//   - number of ring;                                                       //
//   - number of sector;                                                     //
//   - ADC signal in this channel                                            //
//                                                                           //
 //////////////////////////////////////////////////////////////////////////////

#include <TTree.h>
#include <TVector.h>
#include <TObjArray.h>
#include <TFile.h>
#include <TDirectory.h>
#include <TRandom.h>

#include "AliFMDDigitizer.h"
#include "AliFMD.h"
#include "AliFMDhit.h"
#include "AliFMDdigit.h"
#include "AliRunDigitizer.h"

#include "AliRun.h"
#include "AliPDG.h"
#include "AliLoader.h"
#include "AliRunLoader.h"

#include <stdlib.h>
#include <Riostream.h>
#include <Riostream.h>

ClassImp(AliFMDDigitizer)

//___________________________________________
  AliFMDDigitizer::AliFMDDigitizer()  :AliDigitizer()
{
// Default ctor - don't use it
  ;
}

//___________________________________________
AliFMDDigitizer::AliFMDDigitizer(AliRunDigitizer* manager)
    :AliDigitizer(manager)
{
  // ctor which should be used
  //  fDebug =0;
  // if (GetDebug()>2)
  //  cerr<<"AliFMDDigitizer::AliFMDDigitizer"
  //     <<"(AliRunDigitizer* manager) was processed"<<endl;
}

//------------------------------------------------------------------------
AliFMDDigitizer::~AliFMDDigitizer()
{
// Destructor
}

 //------------------------------------------------------------------------
Bool_t AliFMDDigitizer::Init()
{
// Initialization
// cout<<"AliFMDDigitizer::Init"<<endl;
 return kTRUE;
}

//---------------------------------------------------------------------

void AliFMDDigitizer::Exec(Option_t * /*option*/)
{

  /*
   Conver hits to digits:
   - number of detector;
   - number of ring;
   - number of sector;
   - ADC signal in this channel
  */

  AliRunLoader *inRL, *outRL;//in and out Run Loaders
  AliLoader *ingime, *outgime;// in and out ITSLoaders

  outRL = AliRunLoader::GetRunLoader(fManager->GetOutputFolderName());
  outgime = outRL->GetLoader("FMDLoader");

#ifdef DEBUG
  cout<<"AliFMDDigitizer::>SDigits2Digits start...\n";
#endif

  Int_t volume, sector, ring, charge;
  Float_t e;
  Float_t de[10][50][520];
  Int_t hit;
  Int_t digit[5];
  Int_t ivol, iSector, iRing;
  for (Int_t i=0; i<10; i++)
    for(Int_t j=0; j<50; j++)
      for(Int_t ij=0; ij<520; ij++)
     de[i][j][ij]=0;
  Int_t numberOfRings[5]=
  {512,256,512,256,512};
  Int_t numberOfSector[5]=
  {20,40,20,40,20};

  AliFMDhit *fmdHit=0;
  TTree *tH=0;
  TBranch *brHits=0;
  TBranch *brD=0;

  inRL = AliRunLoader::GetRunLoader(fManager->GetInputFolderName(0));
  if (inRL == 0x0)
    {
      Error("Exec","Can not find Run Loader for input stream 0");
      return;
    }
  //  Info("Exec","inRL->GetAliRun() %#x",inRL->GetAliRun());

  if (!inRL->GetAliRun()) inRL->LoadgAlice();

  AliFMD * fFMD = (AliFMD *) inRL->GetAliRun()->GetDetector("FMD");
  //  Info("Exec","inRL->GetAliRun(): %#x, FMD: %#x, InRL %#x.",inRL->GetAliRun(),fFMD,inRL);
  if (fFMD == 0x0)
   {
     Error("Exec","Can not get FMD from gAlice");
     return;
   }
// Loop over files to digitize

  Int_t nFiles=GetManager()->GetNinputs();
  for (Int_t inputFile=0; inputFile<nFiles;inputFile++)
   {
    cout<<" event "<<fManager->GetOutputEventNr()<<endl;
    if (fFMD)
     {

      inRL = AliRunLoader::GetRunLoader(fManager->GetInputFolderName(inputFile));
      ingime = inRL->GetLoader("FMDLoader");
      ingime->LoadHits("READ");//probably it is necessary to load them before

      tH = ingime->TreeH();
      if (tH == 0x0)
       {
         ingime->LoadHits("read");
         tH = ingime->TreeH();
       }
      brHits = tH->GetBranch("FMD");
      if (brHits) {
  //      brHits->SetAddress(&fHits);
          fFMD->SetHitsAddressBranch(brHits);
      }else{
        Fatal("Exec","EXEC Branch FMD hit not found");
      }
      TClonesArray *fFMDhits = fFMD->Hits ();

      Int_t ntracks    = (Int_t) tH->GetEntries();
      cout<<"Number of tracks TreeH"<<ntracks<<endl;
      for (Int_t track = 0; track < ntracks; track++)
       {
         brHits->GetEntry(track);
         Int_t nhits = fFMDhits->GetEntries ();
         // if(nhits>0) cout<<"nhits "<<nhits<<endl;
         for (hit = 0; hit < nhits; hit++)
           {
             fmdHit = (AliFMDhit *) fFMDhits->UncheckedAt(hit);

             volume = fmdHit->Volume ();
             sector = fmdHit->NumberOfSector ();
             ring = fmdHit->NumberOfRing ();
             e = fmdHit->Edep ();
             de[volume][sector][ring] += e;
	     //   if (fManager->GetOutputEventNr()>1)
                    //      cout<<" "<<volume<<" "<<sector<<" "<<ring<<endl;
           }          //hit loop
       }               //track loop
    }
//if FMD

  // Put noise and make ADC signal
   Float_t mipI = 1.664 * 0.04 * 2.33 / 22400;     // = 6.923e-6;
   for ( ivol=1; ivol<=5; ivol++){
     for ( iSector=1; iSector<=numberOfSector[ivol-1]; iSector++){
       for ( iRing=1; iRing<=numberOfRings[ivol-1]; iRing++){
         digit[0]=ivol;
         digit[1]=iSector;
         digit[2]=iRing;
         charge = Int_t (de[ivol][iSector][iRing] / mipI);
         Int_t pedestal=Int_t(gRandom->Gaus(500,250));
  //       digit[3]=PutNoise(charge);
         digit[3]=charge + pedestal;
         if(digit[3]<= 500) digit[3]=500;
    //dynamic range from MIP(0.155MeV) to 30MIP(4.65MeV)
    //1024 ADC channels
         Float_t channelWidth=(22400*50)/1024;
         digit[4]=Int_t(digit[3]/channelWidth);
         if (digit[4]>1024) digit[4]=1024;
         fFMD->AddDigit(digit);
       } //ivol
     } //iSector
   } //iRing

   TTree* treeD = outgime->TreeD();
   cout<<" treeD "<<treeD;
   if (treeD == 0x0) {
     outgime->MakeTree("D");
     treeD = outgime->TreeD();
     cout<<" After MakeTree "<<treeD<<endl;
   }
   cout<<" Before reset "<<treeD<<endl;
   //   treeD->Clear();
   treeD->Reset();
   fFMD->MakeBranchInTreeD(treeD);
   brD = treeD->GetBranch("FMD");
   cout<<" Make branch "<<brD<<endl;

   treeD->Fill();  //this operator does not work for events >1
   //PH   treeD->Print();
   outgime->WriteDigits("OVERWRITE");

   gAlice->ResetDigits();
   }
}

<commit_msg>Reducing printout<commit_after>/**************************************************************************
 * Copyright(c) 1998-2000, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

 //////////////////////////////////////////////////////////////////////////////
//                                                                           //
//  Forward Multiplicity Detector based on Silicon plates                    //
//  This class contains the procedures simulation ADC  signal for            //
//  the Forward Multiplicity detector  : hits -> digits                      //
//  ADC signal consists                                                      //
//   - number of detector;                                                   //
//   - number of ring;                                                       //
//   - number of sector;                                                     //
//   - ADC signal in this channel                                            //
//                                                                           //
 //////////////////////////////////////////////////////////////////////////////

#include <TTree.h>
#include <TVector.h>
#include <TObjArray.h>
#include <TFile.h>
#include <TDirectory.h>
#include <TRandom.h>

#include "AliFMDDigitizer.h"
#include "AliFMD.h"
#include "AliFMDhit.h"
#include "AliFMDdigit.h"
#include "AliRunDigitizer.h"

#include "AliRun.h"
#include "AliPDG.h"
#include "AliLoader.h"
#include "AliRunLoader.h"

#include <stdlib.h>
#include <Riostream.h>
#include <Riostream.h>

ClassImp(AliFMDDigitizer)

//___________________________________________
  AliFMDDigitizer::AliFMDDigitizer()  :AliDigitizer()
{
// Default ctor - don't use it
  ;
}

//___________________________________________
AliFMDDigitizer::AliFMDDigitizer(AliRunDigitizer* manager)
    :AliDigitizer(manager)
{
  // ctor which should be used
  //  fDebug =0;
  // if (GetDebug()>2)
  //  cerr<<"AliFMDDigitizer::AliFMDDigitizer"
  //     <<"(AliRunDigitizer* manager) was processed"<<endl;
}

//------------------------------------------------------------------------
AliFMDDigitizer::~AliFMDDigitizer()
{
// Destructor
}

 //------------------------------------------------------------------------
Bool_t AliFMDDigitizer::Init()
{
// Initialization
// cout<<"AliFMDDigitizer::Init"<<endl;
 return kTRUE;
}

//---------------------------------------------------------------------

void AliFMDDigitizer::Exec(Option_t * /*option*/)
{

  /*
   Conver hits to digits:
   - number of detector;
   - number of ring;
   - number of sector;
   - ADC signal in this channel
  */

  AliRunLoader *inRL, *outRL;//in and out Run Loaders
  AliLoader *ingime, *outgime;// in and out ITSLoaders

  outRL = AliRunLoader::GetRunLoader(fManager->GetOutputFolderName());
  outgime = outRL->GetLoader("FMDLoader");

#ifdef DEBUG
  cout<<"AliFMDDigitizer::>SDigits2Digits start...\n";
#endif

  Int_t volume, sector, ring, charge;
  Float_t e;
  Float_t de[10][50][520];
  Int_t hit;
  Int_t digit[5];
  Int_t ivol, iSector, iRing;
  for (Int_t i=0; i<10; i++)
    for(Int_t j=0; j<50; j++)
      for(Int_t ij=0; ij<520; ij++)
     de[i][j][ij]=0;
  Int_t numberOfRings[5]=
  {512,256,512,256,512};
  Int_t numberOfSector[5]=
  {20,40,20,40,20};

  AliFMDhit *fmdHit=0;
  TTree *tH=0;
  TBranch *brHits=0;
  TBranch *brD=0;

  inRL = AliRunLoader::GetRunLoader(fManager->GetInputFolderName(0));
  if (inRL == 0x0)
    {
      Error("Exec","Can not find Run Loader for input stream 0");
      return;
    }
  //  Info("Exec","inRL->GetAliRun() %#x",inRL->GetAliRun());

  if (!inRL->GetAliRun()) inRL->LoadgAlice();

  AliFMD * fFMD = (AliFMD *) inRL->GetAliRun()->GetDetector("FMD");
  //  Info("Exec","inRL->GetAliRun(): %#x, FMD: %#x, InRL %#x.",inRL->GetAliRun(),fFMD,inRL);
  if (fFMD == 0x0)
   {
     Error("Exec","Can not get FMD from gAlice");
     return;
   }
// Loop over files to digitize

  Int_t nFiles=GetManager()->GetNinputs();
  for (Int_t inputFile=0; inputFile<nFiles;inputFile++)
   {
     //    cout<<" event "<<fManager->GetOutputEventNr()<<endl;
    if (fFMD)
     {

      inRL = AliRunLoader::GetRunLoader(fManager->GetInputFolderName(inputFile));
      ingime = inRL->GetLoader("FMDLoader");
      ingime->LoadHits("READ");//probably it is necessary to load them before

      tH = ingime->TreeH();
      if (tH == 0x0)
       {
         ingime->LoadHits("read");
         tH = ingime->TreeH();
       }
      brHits = tH->GetBranch("FMD");
      if (brHits) {
  //      brHits->SetAddress(&fHits);
          fFMD->SetHitsAddressBranch(brHits);
      }else{
        Fatal("Exec","EXEC Branch FMD hit not found");
      }
      TClonesArray *fFMDhits = fFMD->Hits ();

      Int_t ntracks    = (Int_t) tH->GetEntries();
      //      cout<<"Number of tracks TreeH"<<ntracks<<endl;
      for (Int_t track = 0; track < ntracks; track++)
       {
         brHits->GetEntry(track);
         Int_t nhits = fFMDhits->GetEntries ();
         // if(nhits>0) cout<<"nhits "<<nhits<<endl;
         for (hit = 0; hit < nhits; hit++)
           {
             fmdHit = (AliFMDhit *) fFMDhits->UncheckedAt(hit);

             volume = fmdHit->Volume ();
             sector = fmdHit->NumberOfSector ();
             ring = fmdHit->NumberOfRing ();
             e = fmdHit->Edep ();
             de[volume][sector][ring] += e;
	     //   if (fManager->GetOutputEventNr()>1)
                    //      cout<<" "<<volume<<" "<<sector<<" "<<ring<<endl;
           }          //hit loop
       }               //track loop
    }
//if FMD

  // Put noise and make ADC signal
   Float_t mipI = 1.664 * 0.04 * 2.33 / 22400;     // = 6.923e-6;
   for ( ivol=1; ivol<=5; ivol++){
     for ( iSector=1; iSector<=numberOfSector[ivol-1]; iSector++){
       for ( iRing=1; iRing<=numberOfRings[ivol-1]; iRing++){
         digit[0]=ivol;
         digit[1]=iSector;
         digit[2]=iRing;
         charge = Int_t (de[ivol][iSector][iRing] / mipI);
         Int_t pedestal=Int_t(gRandom->Gaus(500,250));
  //       digit[3]=PutNoise(charge);
         digit[3]=charge + pedestal;
         if(digit[3]<= 500) digit[3]=500;
    //dynamic range from MIP(0.155MeV) to 30MIP(4.65MeV)
    //1024 ADC channels
         Float_t channelWidth=(22400*50)/1024;
         digit[4]=Int_t(digit[3]/channelWidth);
         if (digit[4]>1024) digit[4]=1024;
         fFMD->AddDigit(digit);
       } //ivol
     } //iSector
   } //iRing

   TTree* treeD = outgime->TreeD();
   //   cout<<" treeD "<<treeD;
   if (treeD == 0x0) {
     outgime->MakeTree("D");
     treeD = outgime->TreeD();
     //     cout<<" After MakeTree "<<treeD<<endl;
   }
   //   cout<<" Before reset "<<treeD<<endl;
   //   treeD->Clear();
   treeD->Reset();
   fFMD->MakeBranchInTreeD(treeD);
   brD = treeD->GetBranch("FMD");
   //   cout<<" Make branch "<<brD<<endl;

   treeD->Fill();  //this operator does not work for events >1
   //PH   treeD->Print();
   outgime->WriteDigits("OVERWRITE");

   gAlice->ResetDigits();
   }
}

<|endoftext|>


<commit_before>/**************************************************************************
 * This file is property of and copyright by the ALICE HLT Project        *
 * ALICE Experiment at CERN, All rights reserved.                         *
 *                                                                        *
 * Primary Author: Mikolaj Krzewicki, mikolaj.krzewicki@cern.ch           *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

#include "AliHLTZMQsink.h"
#include "AliHLTErrorGuard.h"
#include "TDatime.h"
#include "TRandom3.h"
#include <TObject.h>
#include <TPRegexp.h>
#include "zmq.h"
#include "AliZMQhelpers.h"

using namespace std;

ClassImp(AliHLTZMQsink)

//______________________________________________________________________________
AliHLTZMQsink::AliHLTZMQsink() :
  AliHLTComponent()
  , fZMQcontext(NULL)
  , fZMQout(NULL)
  , fZMQsocketType(ZMQ_PUB)
  , fZMQendpoint("@tcp://*:60201")
  , fZMQpollIn(kFALSE)
  , fPushbackDelayPeriod(-1)
  , fIncludePrivateBlocks(kFALSE)
  , fZMQneverBlock(kTRUE)
{
  //ctor
}

//______________________________________________________________________________
AliHLTZMQsink::~AliHLTZMQsink()
{
  //dtor
  zmq_close(fZMQout);
  zmq_ctx_destroy(fZMQcontext);
}

//______________________________________________________________________________
const Char_t* AliHLTZMQsink::GetComponentID()
{
  //id
  return "ZMQsink";
}

//______________________________________________________________________________
AliHLTComponentDataType AliHLTZMQsink::GetOutputDataType()
{
  // default method as sink components do not produce output
  AliHLTComponentDataType dt =
    {sizeof(AliHLTComponentDataType),
     kAliHLTVoidDataTypeID,
     kAliHLTVoidDataOrigin};
  return dt;
}

//______________________________________________________________________________
void AliHLTZMQsink::GetInputDataTypes( vector<AliHLTComponentDataType>& list)
{
  //what data types do we accept
  list.clear();
  list.push_back(kAliHLTAllDataTypes);
}

//______________________________________________________________________________
void AliHLTZMQsink::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
{
  // default method as sink components do not produce output
  constBase=0;
  inputMultiplier=0;
}

//______________________________________________________________________________
AliHLTComponent* AliHLTZMQsink::Spawn()
{
  //Spawn a new instance
  return new AliHLTZMQsink();
}

//______________________________________________________________________________
Int_t AliHLTZMQsink::DoInit( Int_t /*argc*/, const Char_t** /*argv*/ )
{
  // see header file for class documentation
  Int_t retCode=0;

  //process arguments
  ProcessOptionString(GetComponentArgs());

  int rc = 0;
  //init ZMQ stuff
  fZMQcontext = zmq_ctx_new();
  HLTMessage(Form("ctx create ptr %p errno %s",fZMQcontext,(rc<0)?strerror(errno):0));
  if (!fZMQcontext) return -1;
  fZMQout = zmq_socket(fZMQcontext, fZMQsocketType);
  HLTMessage(Form("socket create ptr %p errno %s",fZMQout,(rc<0)?strerror(errno):0));
  if (!fZMQout) return -1;

  //set socket options
  int lingerValue = 10;
  rc = zmq_setsockopt(fZMQout, ZMQ_LINGER, &lingerValue, sizeof(int));
  HLTMessage(Form("setopt ZMQ_LINGER=%i   rc=%i errno=%s", lingerValue, rc, (rc<0)?strerror(errno):0));
  int highWaterMarkSend = 100;
  rc = zmq_setsockopt(fZMQout, ZMQ_SNDHWM, &highWaterMarkSend, sizeof(int));
  HLTMessage(Form("setopt ZMQ_SNDHWM=%i   rc=%i errno=%s",highWaterMarkSend, rc, (rc<0)?strerror(errno):0));
  int highWaterMarkRecv = 100;
  rc = zmq_setsockopt(fZMQout, ZMQ_RCVHWM, &highWaterMarkRecv, sizeof(int));
  HLTMessage(Form("setopt ZMQ_RCVHWM=%i   rc=%i errno=%s",highWaterMarkRecv, rc, (rc<0)?strerror(errno):0));
  int rcvtimeo = 0;
  rc = zmq_setsockopt(fZMQout, ZMQ_RCVTIMEO, &rcvtimeo, sizeof(int));
  HLTMessage(Form("setopt ZMQ_RCVTIMEO=%i rc=%i errno=%s",rcvtimeo, rc, (rc<0)?strerror(errno):0));
  int sndtimeo = 0;
  rc = zmq_setsockopt(fZMQout, ZMQ_SNDTIMEO, &sndtimeo, sizeof(int));
  HLTMessage(Form("setopt ZMQ_SNDTIMEO=%i rc=%i errno=%s",sndtimeo, rc, (rc<0)?strerror(errno):0));

  //connect or bind, after setting socket options
  HLTMessage(Form("ZMQ connect to %s",fZMQendpoint.Data()));
  rc = alizmq_attach(fZMQout,fZMQendpoint.Data());
  if (rc==-1) retCode=-1;
  HLTMessage(Form("connect rc %i errno %s",rc,(rc<0)?strerror(errno):0));

  return retCode;
}

//______________________________________________________________________________
Int_t AliHLTZMQsink::DoDeinit()
{
  // see header file for class documentation
  return 0;
}

//______________________________________________________________________________
int AliHLTZMQsink::DoProcessing( const AliHLTComponentEventData& evtData,
                                const AliHLTComponentBlockData* blocks,
                                AliHLTComponentTriggerData& /*trigData*/,
                                AliHLTUInt8_t* /*outputPtr*/,
                                AliHLTUInt32_t& /*size*/,
                                AliHLTComponentBlockDataList& outputBlocks,
                                AliHLTComponentEventDoneData*& /*edd*/ )
{
  // see header file for class documentation
  Int_t retCode=0;

  //create a default selection of any data:
  int requestTopicSize=-1;
  char requestTopic[kAliHLTComponentDataTypeTopicSize];
  memset(requestTopic, '*', kAliHLTComponentDataTypeTopicSize);
  int requestSize=-1;
  char request[kAliHLTComponentDataTypeTopicSize];
  memset(request, '*', kAliHLTComponentDataTypeTopicSize);

  int rc = 0;
  Bool_t doSend = kTRUE;

  //in case we reply to requests instead of just pushing/publishing
  //we poll for requests
  if (fZMQpollIn)
  {
    zmq_pollitem_t items[] = { { fZMQout, 0, ZMQ_POLLIN, 0 } };
    zmq_poll(items, 1, 0);

    if (items[0].revents & ZMQ_POLLIN)
    {
      int64_t more=0;
      size_t moreSize=sizeof(more);
      do //request could be multipart, get all parts
      {
        requestTopicSize = zmq_recv (fZMQout, requestTopic, kAliHLTComponentDataTypeTopicSize, 0);
        zmq_getsockopt(fZMQout, ZMQ_RCVMORE, &more, &moreSize);
        if (more) {
          requestSize = zmq_recv(fZMQout, request, kAliHLTComponentDataTypeTopicSize, 0);
          zmq_getsockopt(fZMQout, ZMQ_RCVMORE, &more, &moreSize);
        }
      } while (more==1);
    }
    else { doSend = kFALSE; }
  }

  //if enabled (option -pushback-period), send at most so often
  if (fPushbackDelayPeriod>0)
  {
    TDatime time;
    if ((Int_t)time.Get()-fLastPushbackDelayTime<fPushbackDelayPeriod)
    {
      doSend=kFALSE;
    }
  }

  if (doSend)
  {
    //set the time of current push
    if (fPushbackDelayPeriod>0)
    {
      TDatime time;
      fLastPushbackDelayTime=time.Get();
    }

    //first make a map of selected blocks, and identify the last one
    //so we can properly mark the last block for multipart ZMQ sending later
    const AliHLTComponentBlockData* inputBlock = NULL;
    std::vector<int> selectedBlockIdx;
    for (int iBlock = 0;
         iBlock < evtData.fBlockCnt;
         iBlock++)
    {
      inputBlock = &blocks[iBlock];
      //don't include provate data unless explicitly asked to
      if (!fIncludePrivateBlocks)
      {
        if (!memcmp(inputBlock->fDataType.fOrigin, &kAliHLTDataOriginPrivate, kAliHLTComponentDataTypefOriginSize))
          continue;
      }

      //check if the data type matches the request
      char blockTopic[kAliHLTComponentDataTypeTopicSize];
      DataType2Topic(inputBlock->fDataType, blockTopic);
      if (Topicncmp(requestTopic, blockTopic, requestTopicSize))
      {
        selectedBlockIdx.push_back(iBlock);
      }
    }

    //send the selected blocks
    for (int iSelectedBlock = 0;
         iSelectedBlock < selectedBlockIdx.size();
         iSelectedBlock++)
    {
      inputBlock = &blocks[selectedBlockIdx[iSelectedBlock]];
      AliHLTDataTopic blockTopic = *inputBlock;

      //send:
      //  first part : AliHLTComponentDataType in string format
      //  second part: Payload
      rc = zmq_send(fZMQout, &blockTopic, sizeof(blockTopic), ZMQ_SNDMORE);
      HLTMessage(Form("send topic rc %i errno %s",rc,(rc<0)?strerror(errno):0));
      int flags = 0;
      if (fZMQneverBlock) flags = ZMQ_DONTWAIT;
      if (iSelectedBlock < (selectedBlockIdx.size()-1)) flags = ZMQ_SNDMORE;
      rc = zmq_send(fZMQout, inputBlock->fPtr, inputBlock->fSize, flags);
      HLTMessage(Form("send data rc %i errno, %s",rc,(rc<0)?strerror(errno):""));
    }

    //send an empty message if we really need a reply (ZMQ_REP mode)
    //only in case no blocks were selected
    if (selectedBlockIdx.size() == 0 && fZMQsocketType==ZMQ_REP)
    {
      rc = zmq_send(fZMQout, 0, 0, ZMQ_SNDMORE);
      HLTMessage(Form("send endframe rc %i errno %s",rc,(rc<0)?strerror(errno):0));
      rc = zmq_send(fZMQout, 0, 0, 0);
      HLTMessage(Form("send endframe rc %i errno %s",rc,(rc<0)?strerror(errno):0));
    }
  }

  outputBlocks.clear();
  return retCode;
}

//______________________________________________________________________________
int AliHLTZMQsink::ProcessOption(TString option, TString value)
{
  //process option
  //to be implemented by the user

  //if (option.EqualTo("ZMQpollIn"))
  //{
  //  fZMQpollIn = (value.EqualTo("0"))?kFALSE:kTRUE;
  //}

  if (option.EqualTo("ZMQsocketMode"))
  {
    if (value.EqualTo("PUB"))  fZMQsocketType=ZMQ_PUB;
    if (value.EqualTo("REP"))  fZMQsocketType=ZMQ_REP;
    if (value.EqualTo("PUSH")) fZMQsocketType=ZMQ_PUSH;

    //always poll when REPlying
    fZMQpollIn=(fZMQsocketType==ZMQ_REP)?kTRUE:kFALSE;
  }

  if (option.EqualTo("ZMQendpoint"))
  {
    fZMQendpoint = value;
  }

  if (option.EqualTo("pushback-period"))
  {
    HLTMessage(Form("Setting pushback delay to %i", atoi(value.Data())));
    fPushbackDelayPeriod = atoi(value.Data());
  }

  if (option.EqualTo("IncludePrivateBlocks"))
  {
    fIncludePrivateBlocks=kTRUE;
  }

  if (option.EqualTo("ZMQneverBlock"))
  {
    if (value.EqualTo("0") || value.EqualTo("no") || value.Contains("false",TString::kIgnoreCase))
      fZMQneverBlock = kFALSE;
    else if (value.EqualTo("1") || value.EqualTo("yes") || value.Contains("true",TString::kIgnoreCase) )
      fZMQneverBlock = kTRUE;
  }

  return 1;
}

////////////////////////////////////////////////////////////////////////////////

//______________________________________________________________________________
int AliHLTZMQsink::ProcessOptionString(TString arguments)
{
  //process passed options
  HLTMessage("Argument string: %s\n", arguments.Data());
  stringMap* options = TokenizeOptionString(arguments);
  for (stringMap::iterator i=options->begin(); i!=options->end(); ++i)
  {
    HLTMessage("  %s : %s", i->first.data(), i->second.data());
    ProcessOption(i->first,i->second);
  }
  delete options; //tidy up

  return 1;
}

//______________________________________________________________________________
AliHLTZMQsink::stringMap* AliHLTZMQsink::TokenizeOptionString(const TString str)
{
  //options have the form:
  // -option value
  // -option=value
  // -option
  // --option value
  // --option=value
  // --option
  // option=value
  // option value
  // (value can also be a string like 'some string')
  //
  // options can be separated by ' ' or ',' arbitrarily combined, e.g:
  //"-option option1=value1 --option2 value2, -option4=\'some string\'"

  //optionRE by construction contains a pure option name as 3rd submatch (without --,-, =)
  //valueRE does NOT match options
  TPRegexp optionRE("(?:(-{1,2})|((?='?[^,=]+=?)))"
                    "((?(2)(?:(?(?=')'(?:[^'\\\\]++|\\.)*+'|[^, =]+))(?==?))"
                    "(?(1)[^, =]+(?=[= ,$])))");
  TPRegexp valueRE("(?(?!(-{1,2}|[^, =]+=))"
                   "(?(?=')'(?:[^'\\\\]++|\\.)*+'"
                   "|[^, =]+))");

  stringMap* options = new stringMap;

  TArrayI pos;
  const TString mods="";
  Int_t start = 0;
  while (1) {
    Int_t prevStart=start;
    TString optionStr="";
    TString valueStr="";

    //check if we have a new option in this field
    Int_t nOption=optionRE.Match(str,mods,start,10,&pos);
    if (nOption>0)
    {
      optionStr = str(pos[6],pos[7]-pos[6]);
      optionStr=optionStr.Strip(TString::kBoth,'\'');
      start=pos[1]; //update the current character to the end of match
    }

    //check if the next field is a value
    Int_t nValue=valueRE.Match(str,mods,start,10,&pos);
    if (nValue>0)
    {
      valueStr = str(pos[0],pos[1]-pos[0]);
      valueStr=valueStr.Strip(TString::kBoth,'\'');
      start=pos[1]; //update the current character to the end of match
    }

    //skip empty entries
    if (nOption>0 || nValue>0)
    {
      (*options)[optionStr.Data()] = valueStr.Data();
    }

    if (start>=str.Length()-1 || start==prevStart ) break;
  }

  //for (stringMap::iterator i=options->begin(); i!=options->end(); ++i)
  //{
  //  printf("%s : %s\n", i->first.data(), i->second.data());
  //}
  return options;
}
<commit_msg>use zmq_strerror() instead of standard one<commit_after>/**************************************************************************
 * This file is property of and copyright by the ALICE HLT Project        *
 * ALICE Experiment at CERN, All rights reserved.                         *
 *                                                                        *
 * Primary Author: Mikolaj Krzewicki, mikolaj.krzewicki@cern.ch           *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

#include "AliHLTZMQsink.h"
#include "AliHLTErrorGuard.h"
#include "TDatime.h"
#include "TRandom3.h"
#include <TObject.h>
#include <TPRegexp.h>
#include "zmq.h"
#include "AliZMQhelpers.h"

using namespace std;

ClassImp(AliHLTZMQsink)

//______________________________________________________________________________
AliHLTZMQsink::AliHLTZMQsink() :
  AliHLTComponent()
  , fZMQcontext(NULL)
  , fZMQout(NULL)
  , fZMQsocketType(ZMQ_PUB)
  , fZMQendpoint("@tcp://*:60201")
  , fZMQpollIn(kFALSE)
  , fPushbackDelayPeriod(-1)
  , fIncludePrivateBlocks(kFALSE)
  , fZMQneverBlock(kTRUE)
{
  //ctor
}

//______________________________________________________________________________
AliHLTZMQsink::~AliHLTZMQsink()
{
  //dtor
  zmq_close(fZMQout);
  zmq_ctx_destroy(fZMQcontext);
}

//______________________________________________________________________________
const Char_t* AliHLTZMQsink::GetComponentID()
{
  //id
  return "ZMQsink";
}

//______________________________________________________________________________
AliHLTComponentDataType AliHLTZMQsink::GetOutputDataType()
{
  // default method as sink components do not produce output
  AliHLTComponentDataType dt =
    {sizeof(AliHLTComponentDataType),
     kAliHLTVoidDataTypeID,
     kAliHLTVoidDataOrigin};
  return dt;
}

//______________________________________________________________________________
void AliHLTZMQsink::GetInputDataTypes( vector<AliHLTComponentDataType>& list)
{
  //what data types do we accept
  list.clear();
  list.push_back(kAliHLTAllDataTypes);
}

//______________________________________________________________________________
void AliHLTZMQsink::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
{
  // default method as sink components do not produce output
  constBase=0;
  inputMultiplier=0;
}

//______________________________________________________________________________
AliHLTComponent* AliHLTZMQsink::Spawn()
{
  //Spawn a new instance
  return new AliHLTZMQsink();
}

//______________________________________________________________________________
Int_t AliHLTZMQsink::DoInit( Int_t /*argc*/, const Char_t** /*argv*/ )
{
  // see header file for class documentation
  Int_t retCode=0;

  //process arguments
  ProcessOptionString(GetComponentArgs());

  int rc = 0;
  //init ZMQ stuff
  fZMQcontext = zmq_ctx_new();
  HLTMessage(Form("ctx create ptr %p errno %s",fZMQcontext,(rc<0)?zmq_strerror(errno):0));
  if (!fZMQcontext) return -1;
  fZMQout = zmq_socket(fZMQcontext, fZMQsocketType);
  HLTMessage(Form("socket create ptr %p errno %s",fZMQout,(rc<0)?zmq_strerror(errno):0));
  if (!fZMQout) return -1;

  //set socket options
  int lingerValue = 10;
  rc = zmq_setsockopt(fZMQout, ZMQ_LINGER, &lingerValue, sizeof(int));
  HLTMessage(Form("setopt ZMQ_LINGER=%i   rc=%i errno=%s", lingerValue, rc, (rc<0)?zmq_strerror(errno):0));
  int highWaterMarkSend = 100;
  rc = zmq_setsockopt(fZMQout, ZMQ_SNDHWM, &highWaterMarkSend, sizeof(int));
  HLTMessage(Form("setopt ZMQ_SNDHWM=%i   rc=%i errno=%s",highWaterMarkSend, rc, (rc<0)?zmq_strerror(errno):0));
  int highWaterMarkRecv = 100;
  rc = zmq_setsockopt(fZMQout, ZMQ_RCVHWM, &highWaterMarkRecv, sizeof(int));
  HLTMessage(Form("setopt ZMQ_RCVHWM=%i   rc=%i errno=%s",highWaterMarkRecv, rc, (rc<0)?zmq_strerror(errno):0));
  int rcvtimeo = 0;
  rc = zmq_setsockopt(fZMQout, ZMQ_RCVTIMEO, &rcvtimeo, sizeof(int));
  HLTMessage(Form("setopt ZMQ_RCVTIMEO=%i rc=%i errno=%s",rcvtimeo, rc, (rc<0)?zmq_strerror(errno):0));
  int sndtimeo = 0;
  rc = zmq_setsockopt(fZMQout, ZMQ_SNDTIMEO, &sndtimeo, sizeof(int));
  HLTMessage(Form("setopt ZMQ_SNDTIMEO=%i rc=%i errno=%s",sndtimeo, rc, (rc<0)?zmq_strerror(errno):0));

  //connect or bind, after setting socket options
  HLTMessage(Form("ZMQ connect to %s",fZMQendpoint.Data()));
  rc = alizmq_attach(fZMQout,fZMQendpoint.Data());
  if (rc==-1) retCode=-1;
  HLTMessage(Form("connect rc %i errno %s",rc,(rc<0)?zmq_strerror(errno):0));

  return retCode;
}

//______________________________________________________________________________
Int_t AliHLTZMQsink::DoDeinit()
{
  // see header file for class documentation
  return 0;
}

//______________________________________________________________________________
int AliHLTZMQsink::DoProcessing( const AliHLTComponentEventData& evtData,
                                const AliHLTComponentBlockData* blocks,
                                AliHLTComponentTriggerData& /*trigData*/,
                                AliHLTUInt8_t* /*outputPtr*/,
                                AliHLTUInt32_t& /*size*/,
                                AliHLTComponentBlockDataList& outputBlocks,
                                AliHLTComponentEventDoneData*& /*edd*/ )
{
  // see header file for class documentation
  Int_t retCode=0;

  //create a default selection of any data:
  int requestTopicSize=-1;
  char requestTopic[kAliHLTComponentDataTypeTopicSize];
  memset(requestTopic, '*', kAliHLTComponentDataTypeTopicSize);
  int requestSize=-1;
  char request[kAliHLTComponentDataTypeTopicSize];
  memset(request, '*', kAliHLTComponentDataTypeTopicSize);

  int rc = 0;
  Bool_t doSend = kTRUE;

  //in case we reply to requests instead of just pushing/publishing
  //we poll for requests
  if (fZMQpollIn)
  {
    zmq_pollitem_t items[] = { { fZMQout, 0, ZMQ_POLLIN, 0 } };
    zmq_poll(items, 1, 0);

    if (items[0].revents & ZMQ_POLLIN)
    {
      int64_t more=0;
      size_t moreSize=sizeof(more);
      do //request could be multipart, get all parts
      {
        requestTopicSize = zmq_recv (fZMQout, requestTopic, kAliHLTComponentDataTypeTopicSize, 0);
        zmq_getsockopt(fZMQout, ZMQ_RCVMORE, &more, &moreSize);
        if (more) {
          requestSize = zmq_recv(fZMQout, request, kAliHLTComponentDataTypeTopicSize, 0);
          zmq_getsockopt(fZMQout, ZMQ_RCVMORE, &more, &moreSize);
        }
      } while (more==1);
    }
    else { doSend = kFALSE; }
  }

  //if enabled (option -pushback-period), send at most so often
  if (fPushbackDelayPeriod>0)
  {
    TDatime time;
    if ((Int_t)time.Get()-fLastPushbackDelayTime<fPushbackDelayPeriod)
    {
      doSend=kFALSE;
    }
  }

  if (doSend)
  {
    //set the time of current push
    if (fPushbackDelayPeriod>0)
    {
      TDatime time;
      fLastPushbackDelayTime=time.Get();
    }

    //first make a map of selected blocks, and identify the last one
    //so we can properly mark the last block for multipart ZMQ sending later
    const AliHLTComponentBlockData* inputBlock = NULL;
    std::vector<int> selectedBlockIdx;
    for (int iBlock = 0;
         iBlock < evtData.fBlockCnt;
         iBlock++)
    {
      inputBlock = &blocks[iBlock];
      //don't include provate data unless explicitly asked to
      if (!fIncludePrivateBlocks)
      {
        if (!memcmp(inputBlock->fDataType.fOrigin, &kAliHLTDataOriginPrivate, kAliHLTComponentDataTypefOriginSize))
          continue;
      }

      //check if the data type matches the request
      char blockTopic[kAliHLTComponentDataTypeTopicSize];
      DataType2Topic(inputBlock->fDataType, blockTopic);
      if (Topicncmp(requestTopic, blockTopic, requestTopicSize))
      {
        selectedBlockIdx.push_back(iBlock);
      }
    }

    //send the selected blocks
    for (int iSelectedBlock = 0;
         iSelectedBlock < selectedBlockIdx.size();
         iSelectedBlock++)
    {
      inputBlock = &blocks[selectedBlockIdx[iSelectedBlock]];
      AliHLTDataTopic blockTopic = *inputBlock;

      //send:
      //  first part : AliHLTComponentDataType in string format
      //  second part: Payload
      rc = zmq_send(fZMQout, &blockTopic, sizeof(blockTopic), ZMQ_SNDMORE);
      HLTMessage(Form("send topic rc %i errno %s",rc,(rc<0)?zmq_strerror(errno):0));
      int flags = 0;
      if (fZMQneverBlock) flags = ZMQ_DONTWAIT;
      if (iSelectedBlock < (selectedBlockIdx.size()-1)) flags = ZMQ_SNDMORE;
      rc = zmq_send(fZMQout, inputBlock->fPtr, inputBlock->fSize, flags);
      HLTMessage(Form("send data rc %i errno, %s",rc,(rc<0)?zmq_strerror(errno):""));
    }

    //send an empty message if we really need a reply (ZMQ_REP mode)
    //only in case no blocks were selected
    if (selectedBlockIdx.size() == 0 && fZMQsocketType==ZMQ_REP)
    {
      rc = zmq_send(fZMQout, 0, 0, ZMQ_SNDMORE);
      HLTMessage(Form("send endframe rc %i errno %s",rc,(rc<0)?zmq_strerror(errno):0));
      rc = zmq_send(fZMQout, 0, 0, 0);
      HLTMessage(Form("send endframe rc %i errno %s",rc,(rc<0)?zmq_strerror(errno):0));
    }
  }

  outputBlocks.clear();
  return retCode;
}

//______________________________________________________________________________
int AliHLTZMQsink::ProcessOption(TString option, TString value)
{
  //process option
  //to be implemented by the user

  //if (option.EqualTo("ZMQpollIn"))
  //{
  //  fZMQpollIn = (value.EqualTo("0"))?kFALSE:kTRUE;
  //}

  if (option.EqualTo("ZMQsocketMode"))
  {
    if (value.EqualTo("PUB"))  fZMQsocketType=ZMQ_PUB;
    if (value.EqualTo("REP"))  fZMQsocketType=ZMQ_REP;
    if (value.EqualTo("PUSH")) fZMQsocketType=ZMQ_PUSH;

    //always poll when REPlying
    fZMQpollIn=(fZMQsocketType==ZMQ_REP)?kTRUE:kFALSE;
  }

  if (option.EqualTo("ZMQendpoint"))
  {
    fZMQendpoint = value;
  }

  if (option.EqualTo("pushback-period"))
  {
    HLTMessage(Form("Setting pushback delay to %i", atoi(value.Data())));
    fPushbackDelayPeriod = atoi(value.Data());
  }

  if (option.EqualTo("IncludePrivateBlocks"))
  {
    fIncludePrivateBlocks=kTRUE;
  }

  if (option.EqualTo("ZMQneverBlock"))
  {
    if (value.EqualTo("0") || value.EqualTo("no") || value.Contains("false",TString::kIgnoreCase))
      fZMQneverBlock = kFALSE;
    else if (value.EqualTo("1") || value.EqualTo("yes") || value.Contains("true",TString::kIgnoreCase) )
      fZMQneverBlock = kTRUE;
  }

  return 1;
}

////////////////////////////////////////////////////////////////////////////////

//______________________________________________________________________________
int AliHLTZMQsink::ProcessOptionString(TString arguments)
{
  //process passed options
  HLTMessage("Argument string: %s\n", arguments.Data());
  stringMap* options = TokenizeOptionString(arguments);
  for (stringMap::iterator i=options->begin(); i!=options->end(); ++i)
  {
    HLTMessage("  %s : %s", i->first.data(), i->second.data());
    ProcessOption(i->first,i->second);
  }
  delete options; //tidy up

  return 1;
}

//______________________________________________________________________________
AliHLTZMQsink::stringMap* AliHLTZMQsink::TokenizeOptionString(const TString str)
{
  //options have the form:
  // -option value
  // -option=value
  // -option
  // --option value
  // --option=value
  // --option
  // option=value
  // option value
  // (value can also be a string like 'some string')
  //
  // options can be separated by ' ' or ',' arbitrarily combined, e.g:
  //"-option option1=value1 --option2 value2, -option4=\'some string\'"

  //optionRE by construction contains a pure option name as 3rd submatch (without --,-, =)
  //valueRE does NOT match options
  TPRegexp optionRE("(?:(-{1,2})|((?='?[^,=]+=?)))"
                    "((?(2)(?:(?(?=')'(?:[^'\\\\]++|\\.)*+'|[^, =]+))(?==?))"
                    "(?(1)[^, =]+(?=[= ,$])))");
  TPRegexp valueRE("(?(?!(-{1,2}|[^, =]+=))"
                   "(?(?=')'(?:[^'\\\\]++|\\.)*+'"
                   "|[^, =]+))");

  stringMap* options = new stringMap;

  TArrayI pos;
  const TString mods="";
  Int_t start = 0;
  while (1) {
    Int_t prevStart=start;
    TString optionStr="";
    TString valueStr="";

    //check if we have a new option in this field
    Int_t nOption=optionRE.Match(str,mods,start,10,&pos);
    if (nOption>0)
    {
      optionStr = str(pos[6],pos[7]-pos[6]);
      optionStr=optionStr.Strip(TString::kBoth,'\'');
      start=pos[1]; //update the current character to the end of match
    }

    //check if the next field is a value
    Int_t nValue=valueRE.Match(str,mods,start,10,&pos);
    if (nValue>0)
    {
      valueStr = str(pos[0],pos[1]-pos[0]);
      valueStr=valueStr.Strip(TString::kBoth,'\'');
      start=pos[1]; //update the current character to the end of match
    }

    //skip empty entries
    if (nOption>0 || nValue>0)
    {
      (*options)[optionStr.Data()] = valueStr.Data();
    }

    if (start>=str.Length()-1 || start==prevStart ) break;
  }

  //for (stringMap::iterator i=options->begin(); i!=options->end(); ++i)
  //{
  //  printf("%s : %s\n", i->first.data(), i->second.data());
  //}
  return options;
}
<|endoftext|>


<commit_before>/* The Halfling Project - A Graphics Engine and Projects
 *
 * The Halfling Project is the legal property of Adrian Astley
 * Copyright Adrian Astley 2013
 */

#include "common/texture_manager.h"

#include "common/halfling_sys.h"
#include "common/d3d_util.h"
#include "DDSTextureLoader.h"

namespace Common {

TextureManager::~TextureManager() {
	for (auto bucket = m_textureCache.begin(); bucket != m_textureCache.end(); ++bucket) {
		for (auto bucketIter = bucket->second.begin(); bucketIter != bucket->second.end(); ++bucketIter) {
			ReleaseCOM(bucketIter->second);
		}
	}
}

ID3D11ShaderResourceView * TextureManager::GetSRVFromFile(ID3D11Device *device, const std::wstring filePath, D3D11_USAGE usage, uint bindFlags, uint cpuAccessFlags, uint miscFlags, bool forceSRGB) {
	if (filePath.compare(filePath.length() - 4, std::string::npos, L".dds") == 0 || filePath.compare(filePath.length() - 4, std::string::npos, L".DDS") == 0) {
		return GetSRVFromDDSFile(device, filePath, usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB);
	} else {
		return nullptr;
	}
}

ID3D11ShaderResourceView *TextureManager::GetSRVFromDDSFile(ID3D11Device *device, const std::wstring filePath, D3D11_USAGE usage, uint bindFlags, uint cpuAccessFlags, uint miscFlags, bool forceSRGB) {
	// First check the cache
	auto bucket = m_textureCache.find(filePath);
	if (bucket != m_textureCache.end()) {
		for (auto iter = bucket->second.begin(); iter != bucket->second.end(); ++iter) {
			if (usage == iter->first.Usage &&
				bindFlags == iter->first.BindFlags &&
				cpuAccessFlags == iter->first.CpuAccessFlags &&
				miscFlags == iter->first.MiscFlags &&
				forceSRGB == iter->first.ForceSRGB) {

				return iter->second;
			}
		}
	}

	// Else create it from scratch
	ID3D11ShaderResourceView *newSRV;
	HR(DirectX::CreateDDSTextureFromFileEx(device, filePath.c_str(), 0, usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB, nullptr, &newSRV));

	// Store the new SRV in cache
	TextureParams newParams {usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB};
	m_textureCache[filePath].push_back(std::pair<TextureParams, ID3D11ShaderResourceView *>(newParams, newSRV));

	// Finally return the SRV
	return newSRV;
}

} // End of namespace Common
<commit_msg>COMMON: Fix file extension comparisons<commit_after>/* The Halfling Project - A Graphics Engine and Projects
 *
 * The Halfling Project is the legal property of Adrian Astley
 * Copyright Adrian Astley 2013
 */

#include "common/texture_manager.h"

#include "common/halfling_sys.h"
#include "common/d3d_util.h"
#include "DDSTextureLoader.h"

namespace Common {

TextureManager::~TextureManager() {
	for (auto bucket = m_textureCache.begin(); bucket != m_textureCache.end(); ++bucket) {
		for (auto bucketIter = bucket->second.begin(); bucketIter != bucket->second.end(); ++bucketIter) {
			ReleaseCOM(bucketIter->second);
		}
	}
}

ID3D11ShaderResourceView * TextureManager::GetSRVFromFile(ID3D11Device *device, const std::wstring filePath, D3D11_USAGE usage, uint bindFlags, uint cpuAccessFlags, uint miscFlags, bool forceSRGB) {
	if (filePath.compare(filePath.length() - 5, 4, L".dds") == 0 || filePath.compare(filePath.length() - 5, 4, L".DDS") == 0) {
		return GetSRVFromDDSFile(device, filePath, usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB);
	} else {
		return nullptr;
	}
}

ID3D11ShaderResourceView *TextureManager::GetSRVFromDDSFile(ID3D11Device *device, const std::wstring filePath, D3D11_USAGE usage, uint bindFlags, uint cpuAccessFlags, uint miscFlags, bool forceSRGB) {
	// First check the cache
	auto bucket = m_textureCache.find(filePath);
	if (bucket != m_textureCache.end()) {
		for (auto iter = bucket->second.begin(); iter != bucket->second.end(); ++iter) {
			if (usage == iter->first.Usage &&
				bindFlags == iter->first.BindFlags &&
				cpuAccessFlags == iter->first.CpuAccessFlags &&
				miscFlags == iter->first.MiscFlags &&
				forceSRGB == iter->first.ForceSRGB) {

				return iter->second;
			}
		}
	}

	// Else create it from scratch
	ID3D11ShaderResourceView *newSRV;
	HR(DirectX::CreateDDSTextureFromFileEx(device, filePath.c_str(), 0, usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB, nullptr, &newSRV));

	// Store the new SRV in cache
	TextureParams newParams {usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB};
	m_textureCache[filePath].push_back(std::pair<TextureParams, ID3D11ShaderResourceView *>(newParams, newSRV));

	// Finally return the SRV
	return newSRV;
}

} // End of namespace Common
<|endoftext|>