<commit_before>#ifndef ALGORITHM_HUFFMAN_H_
#define ALGORITHM_HUFFMAN_H_ 1

#include <fstream>
#include <vector>
#include <array>
#include <limits>
#include <string>
#include <cstring>

namespace algorithm
{

/** \breif  Modified Huffman coding

    Huffman coding method with Run Length Encoding.
    Combines the variable length codes of Huffman coding with the
    coding of repetitive data in Run Length Encoding.
*/
class Huffman
{
public:
    typedef size_t          SizeType;

    typedef std::ifstream   FileStreamInType;
    typedef std::ofstream   FileStreamOutType;

    typedef std::string     StringType;

    typedef uint8_t         ByteType;       /** One byte */
    typedef uint32_t        CodewordType;   /** Codeword, consists of 4 bytes */

    typedef std::pair<ByteType, SizeType> MetaSymbolType;

    /** Constants */
    static  const ByteType  zerobit     = 0;
    static  const ByteType  nonzerobit  = 1;
    static  const SizeType  ascii_max   = std::numeric_limits<ByteType>::max();

    static  const SizeType  byte_size   = 8;                /**< 8 bits, bit size of ByteType */
    static  const SizeType  buffer_size = byte_size * 4;    /**< Bit size of CodewordType */

    /** Class for each node in Huffman tree, and used in RLE */
    struct Run
    {
        /** MetaSymbol, paired with MetaSymbolType */
        ByteType        symbol;         /**< ASCII character */
        SizeType        run_len;        /**< Run-length, used in RLE */

        /** For Heap, and Huffman coding */
        SizeType        freq;           /**< Frequency of the MetaSymbol */

        /** For Huffman Tree */
        Run *           left;           /**< Left child node */
        Run *           right;          /**< Right child node */
        CodewordType    codeword;       /**< Huffman codeword */
        SizeType        codeword_len;   /**< Length of member `codeword' */

        /** For ArrayList */
        Run *           next;

        /** Contructors */
        Run(const ByteType & symbol, const SizeType & run_len, const SizeType & freq = 0)
        : symbol        (symbol)
        , run_len       (run_len)
        , freq          (freq)
        , left          (nullptr)
        , right         (nullptr)
        , codeword      (0)
        , codeword_len  (0)
        , next          (nullptr)
        { }

        Run(const MetaSymbolType & meta_symbol, const SizeType & freq = 0)
        : symbol        (meta_symbol.first)
        , run_len       (meta_symbol.second)
        , freq          (freq)
        , left          (nullptr)
        , right         (nullptr)
        , codeword      (0)
        , codeword_len  (0)
        , next          (nullptr)
        { }

        Run(const Run & run)
        : symbol        (run.symbol)
        , run_len       (run.run_len)
        , freq          (run.freq)
        , left          (run.left)
        , right         (run.right)
        , codeword      (run.codeword)
        , codeword_len  (run.codeword_len)
        , next          (run.next)
        { }

        Run(Run * left, Run * right)
        : symbol        (0)
        , run_len       (0)
        , freq          (left->freq + right->freq)
        , left          (left)
        , right         (right)
        , codeword      (0)
        , codeword_len  (0)
        , next          (nullptr)
        { }

        /** Operators */
        inline
        Run &
        operator=(Run run)
        {
            this->symbol        = run.symbol;
            this->run_len       = run.run_len;
            this->freq          = run.freq;
            this->left          = run.left;
            this->right         = run.right;
            this->codeword      = run.codeword;
            this->codeword_len  = run.codeword_len;
            this->next          = run.next;

            return *this;
        }

        inline
        bool
        operator==(const Run & rhs)
        const
        { return symbol == rhs.symbol && run_len == rhs.run_len; }

        inline
        bool
        operator!=(const Run & rhs)
        const
        { return ! (*this == rhs); }

        inline
        Run &
        operator++(void)
        {
            ++freq;
            return *this;
        }

        inline
        Run
        operator++(int)
        {
            Run temp(*this);
            operator++();
            return temp;
        }

        inline
        Run &
        operator--(void)
        {
            --freq;
            return *this;
        }

        inline
        Run
        operator--(int)
        {
            Run temp(*this);
            operator--();
            return temp;
        }

        inline
        bool
        operator<(const Run & rhs)
        const
        { return (this->freq < rhs.freq); }

        inline
        bool
        operator>(const Run & rhs)
        const
        { return (this->freq > rhs.freq); }

        inline
        bool
        operator<=(const Run & rhs)
        const
        { return ! operator>(rhs); }

        inline
        bool
        operator>=(const Run & rhs)
        const
        { return ! operator<(rhs); }
    };

    typedef Run     RunType;

    typedef std::vector<RunType>    RunArrayType;
    typedef RunType *               HuffmanTreeType;
    typedef std::array<RunType *, ascii_max + 1>    RunListType;

private:
    /** Member data */
    RunArrayType        runs_;      /** Set of runs */
    RunListType         list_;      /** ArrayList of runs, for symbol searching efficiency */
    HuffmanTreeType     root_;      /** Root node of the Huffman tree */

    /** Member functions */
    template<typename T = CodewordType>
    void
    WriteToFile(FileStreamOutType & fout, T src, const bool & rm_trailing_zerobit = false)
    {
        /** Do not use defualt buffer_size (which is 32) */
        const   SizeType        buffer_size         = 4;
                unsigned char   buffer[buffer_size] = { 0, };

        for(int i = buffer_size - 1; i >= 0; --i)
        {
            buffer[i] = src % (0x1 << 8);
            src >>= 8;
        }

        SizeType last_pos = buffer_size - 1;

        if(rm_trailing_zerobit == true)
            for(; last_pos > 0 && buffer[last_pos] == 0x0; --last_pos);

        fout.write((char *)&buffer, sizeof(unsigned char) * (last_pos + 1));
    }

    template<typename T = ByteType>
    void
    PrintBinary(FILE * fout, T src, const size_t & buffer_size = buffer_size)
    {
        while(src != 0)
        {
            ByteType buffer[buffer_size] = { 0, };

            for(int bpos = buffer_size - 1; bpos >= 0; --bpos)
            {
                buffer[bpos] = ((src % 2 == 0) ? zerobit : nonzerobit);
                src = src >> 1;
            }

            for(int i = 0; i < buffer_size; ++i)
            {
                if(i != 0 && i % 4 == 0)
                    fprintf(fout, " ");

                fprintf(fout, "%d", buffer[i]);
            }

            fprintf(fout, " ");
        }
    }

    void CollectRuns(FileStreamInType &);
    void CreateHuffmanTree(void);
    void AssignCodeword(RunType *, const CodewordType & = 0, const SizeType & = 0);
    void CreateRunList(RunType *);
    SizeType GetCodeword(CodewordType &, const ByteType &, const SizeType &);
    void WriteHeader(FileStreamInType &, FileStreamOutType &);
    void WriteEncode(FileStreamInType &, FileStreamOutType &);
    void PrintHuffmanTree(FILE *, const RunType *, const SizeType &);

public:
    void CompressFile(FileStreamInType &, const StringType &, const StringType &);
    void PrintAllRuns(FILE * = stdout);

    inline
    void
    PrintHuffmanTree(FILE * fout = stdout)
    { PrintHuffmanTree(fout, root_, 0); }
};

} /** ns: algorithm */

#endif /** ! ALGORITHM_HUFFMAN_H_ */
<commit_msg>Add a file stream reader into libhuffman<commit_after>#ifndef ALGORITHM_HUFFMAN_H_
#define ALGORITHM_HUFFMAN_H_ 1

#include <fstream>
#include <vector>
#include <array>
#include <limits>
#include <string>
#include <cstring>

namespace algorithm
{

/** \breif  Modified Huffman coding

    Huffman coding method with Run Length Encoding.
    Combines the variable length codes of Huffman coding with the
    coding of repetitive data in Run Length Encoding.
*/
class Huffman
{
public:
    typedef size_t          SizeType;

    typedef std::ifstream   FileStreamInType;
    typedef std::ofstream   FileStreamOutType;

    typedef std::string     StringType;

    typedef uint8_t         ByteType;       /** One byte */
    typedef uint32_t        CodewordType;   /** Codeword, consists of 4 bytes */

    typedef std::pair<ByteType, SizeType> MetaSymbolType;

    /** Constants */
    static  const ByteType  zerobit     = 0;
    static  const ByteType  nonzerobit  = 1;
    static  const SizeType  ascii_max   = std::numeric_limits<ByteType>::max();

    static  const SizeType  byte_size   = 8;                /**< 8 bits, bit size of ByteType */
    static  const SizeType  buffer_size = byte_size * 4;    /**< Bit size of CodewordType */

    /** Class for each node in Huffman tree, and used in RLE */
    struct Run
    {
        /** MetaSymbol, paired with MetaSymbolType */
        ByteType        symbol;         /**< ASCII character */
        SizeType        run_len;        /**< Run-length, used in RLE */

        /** For Heap, and Huffman coding */
        SizeType        freq;           /**< Frequency of the MetaSymbol */

        /** For Huffman Tree */
        Run *           left;           /**< Left child node */
        Run *           right;          /**< Right child node */
        CodewordType    codeword;       /**< Huffman codeword */
        SizeType        codeword_len;   /**< Length of member `codeword' */

        /** For ArrayList */
        Run *           next;

        /** Contructors */
        Run(const ByteType & symbol, const SizeType & run_len, const SizeType & freq = 0)
        : symbol        (symbol)
        , run_len       (run_len)
        , freq          (freq)
        , left          (nullptr)
        , right         (nullptr)
        , codeword      (0)
        , codeword_len  (0)
        , next          (nullptr)
        { }

        Run(const MetaSymbolType & meta_symbol, const SizeType & freq = 0)
        : symbol        (meta_symbol.first)
        , run_len       (meta_symbol.second)
        , freq          (freq)
        , left          (nullptr)
        , right         (nullptr)
        , codeword      (0)
        , codeword_len  (0)
        , next          (nullptr)
        { }

        Run(const Run & run)
        : symbol        (run.symbol)
        , run_len       (run.run_len)
        , freq          (run.freq)
        , left          (run.left)
        , right         (run.right)
        , codeword      (run.codeword)
        , codeword_len  (run.codeword_len)
        , next          (run.next)
        { }

        Run(Run * left, Run * right)
        : symbol        (0)
        , run_len       (0)
        , freq          (left->freq + right->freq)
        , left          (left)
        , right         (right)
        , codeword      (0)
        , codeword_len  (0)
        , next          (nullptr)
        { }

        /** Operators */
        inline
        Run &
        operator=(Run run)
        {
            this->symbol        = run.symbol;
            this->run_len       = run.run_len;
            this->freq          = run.freq;
            this->left          = run.left;
            this->right         = run.right;
            this->codeword      = run.codeword;
            this->codeword_len  = run.codeword_len;
            this->next          = run.next;

            return *this;
        }

        inline
        bool
        operator==(const Run & rhs)
        const
        { return symbol == rhs.symbol && run_len == rhs.run_len; }

        inline
        bool
        operator!=(const Run & rhs)
        const
        { return ! (*this == rhs); }

        inline
        Run &
        operator++(void)
        {
            ++freq;
            return *this;
        }

        inline
        Run
        operator++(int)
        {
            Run temp(*this);
            operator++();
            return temp;
        }

        inline
        Run &
        operator--(void)
        {
            --freq;
            return *this;
        }

        inline
        Run
        operator--(int)
        {
            Run temp(*this);
            operator--();
            return temp;
        }

        inline
        bool
        operator<(const Run & rhs)
        const
        { return (this->freq < rhs.freq); }

        inline
        bool
        operator>(const Run & rhs)
        const
        { return (this->freq > rhs.freq); }

        inline
        bool
        operator<=(const Run & rhs)
        const
        { return ! operator>(rhs); }

        inline
        bool
        operator>=(const Run & rhs)
        const
        { return ! operator<(rhs); }
    };

    typedef Run     RunType;

    typedef std::vector<RunType>    RunArrayType;
    typedef RunType *               HuffmanTreeType;
    typedef std::array<RunType *, ascii_max + 1>    RunListType;

private:
    /** Member data */
    RunArrayType        runs_;      /** Set of runs */
    RunListType         list_;      /** ArrayList of runs, for symbol searching efficiency */
    HuffmanTreeType     root_;      /** Root node of the Huffman tree */

    /** Member functions */
    template<typename T = CodewordType>
    void
    WriteToFile(FileStreamOutType & fout, T src, const bool & rm_trailing_zerobit = false)
    {
        /** Do not use defualt buffer_size (which is 32) */
        const   SizeType        buffer_size         = 4;
                unsigned char   buffer[buffer_size] = { 0, };

        for(int i = buffer_size - 1; i >= 0; --i)
        {
            buffer[i] = src % (0x1 << 8);
            src >>= 8;
        }

        SizeType last_pos = buffer_size - 1;

        if(rm_trailing_zerobit == true)
            for(; last_pos > 0 && buffer[last_pos] == 0x0; --last_pos);

        fout.write((char *)&buffer, sizeof(unsigned char) * (last_pos + 1));
    }

    template<typename T = CodewordType>
    void
    ReadFromFile(FileStreamInType & fin, T & dest)
    {
        const   SizeType        byte_size           = 8;
        const   SizeType        char_size           = sizeof(unsigned char) * byte_size;
        const   SizeType        type_size           = sizeof(T) * byte_size;
        const   SizeType        buffer_size         = (type_size / char_size)
                                                    + ((type_size % char_size == 0) ? 0 : 1);
                unsigned char   buffer[buffer_size] = { 0, };

        fin.read((char *)&buffer, sizeof(unsigned char) * buffer_size);

        for(int i = 0; i < buffer_size; ++i)
        {
            dest <<= byte_size;
            dest += buffer[i];
        }
    }

    template<typename T = ByteType>
    void
    PrintBinary(FILE * fout, T src, const size_t & buffer_size = buffer_size)
    {
        while(src != 0)
        {
            ByteType buffer[buffer_size] = { 0, };

            for(int bpos = buffer_size - 1; bpos >= 0; --bpos)
            {
                buffer[bpos] = ((src % 2 == 0) ? zerobit : nonzerobit);
                src = src >> 1;
            }

            for(int i = 0; i < buffer_size; ++i)
            {
                if(i != 0 && i % 4 == 0)
                    fprintf(fout, " ");

                fprintf(fout, "%d", buffer[i]);
            }

            fprintf(fout, " ");
        }
    }

    void CollectRuns(FileStreamInType &);
    void CreateHuffmanTree(void);
    void AssignCodeword(RunType *, const CodewordType & = 0, const SizeType & = 0);
    void CreateRunList(RunType *);
    SizeType GetCodeword(CodewordType &, const ByteType &, const SizeType &);
    void WriteHeader(FileStreamInType &, FileStreamOutType &);
    void WriteEncode(FileStreamInType &, FileStreamOutType &);
    void PrintHuffmanTree(FILE *, const RunType *, const SizeType &);

public:
    void CompressFile(FileStreamInType &, const StringType &, const StringType &);
    void PrintAllRuns(FILE * = stdout);

    inline
    void
    PrintHuffmanTree(FILE * fout = stdout)
    { PrintHuffmanTree(fout, root_, 0); }
};

} /** ns: algorithm */

#endif /** ! ALGORITHM_HUFFMAN_H_ */
<|endoftext|>


<commit_before>/* -*- mode: C++; c-file-style: "gnu" -*-
 * kmail: KDE mail client
 * Copyright (c) 1996-1998 Stefan Taferner <taferner@kde.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include "kmfilter.h"
#include "kmkernel.h"
#include "accountmanager.h"
using KMail::AccountManager;
#include "kmacctimap.h"
#include "kmfilteraction.h"
#include "kmglobal.h"
#include "filterlog.h"
using KMail::FilterLog;

#include <klocale.h>
#include <kmessagebox.h>
#include <kdebug.h>
#include <kconfig.h>

#include <assert.h>

KMFilter::KMFilter( KConfig* aConfig, bool popFilter )
  : bPopFilter(popFilter)
{
  if (!bPopFilter)
    mActions.setAutoDelete( true );

  if ( aConfig )
    readConfig( aConfig );
  else if ( bPopFilter )
    mAction = Down;
  else {
    bApplyOnInbound = true;
    bApplyOnOutbound = false;
    bApplyOnExplicit = true;
    bStopProcessingHere = true;
    bConfigureShortcut = false;
    bConfigureToolbar = false;
    bAutoNaming = true;
    mApplicability = All;
  }
}

KMFilter::KMFilter( const KMFilter & aFilter )
{
  bPopFilter = aFilter.isPopFilter();

  if ( !bPopFilter )
    mActions.setAutoDelete( true );

  mPattern = aFilter.mPattern;

  if ( bPopFilter ){
    mAction = aFilter.mAction;
  } else {
    bApplyOnInbound = aFilter.applyOnInbound();
    bApplyOnOutbound = aFilter.applyOnOutbound();
    bApplyOnExplicit = aFilter.applyOnExplicit();
    bStopProcessingHere = aFilter.stopProcessingHere();
    bConfigureShortcut = aFilter.configureShortcut();
    bConfigureToolbar = aFilter.configureToolbar();
    mApplicability = aFilter.applicability();
    mIcon = aFilter.icon();
    mShortcut = aFilter.shortcut();

    QPtrListIterator<KMFilterAction> it( aFilter.mActions );
    for ( it.toFirst() ; it.current() ; ++it ) {
      KMFilterActionDesc *desc = (*kmkernel->filterActionDict())[ (*it)->name() ];
      if ( desc ) {
        KMFilterAction *f = desc->create();
        if ( f ) {
          f->argsFromString( (*it)->argsAsString() );
          mActions.append( f );
        }
      }
    }

    mAccounts.clear();
    QValueListConstIterator<int> it2;
    for ( it2 = aFilter.mAccounts.begin() ; it2 != aFilter.mAccounts.end() ; ++it2 )
      mAccounts.append( *it2 );
  }
}

// only for !bPopFilter
KMFilter::ReturnCode KMFilter::execActions( KMMessage* msg, bool& stopIt ) const
{
  ReturnCode status = NoResult;

  QPtrListIterator<KMFilterAction> it( mActions );
  for ( it.toFirst() ; it.current() ; ++it ) {

    if ( FilterLog::instance()->isLogging() ) {
      QString logText( i18n( "Applying filter action: %1" )
                       .arg( (*it)->displayString() ) );
      FilterLog::instance()->add( logText, FilterLog::appliedAction );
    }

    KMFilterAction::ReturnCode result = (*it)->process( msg );

    switch ( result ) {
    case KMFilterAction::CriticalError:
      if ( FilterLog::instance()->isLogging() ) {
        QString logText = QString( "%1" )
          .arg( i18n( "A critical error occurred. Processing stops here." ) );
        FilterLog::instance()->add( logText, FilterLog::appliedAction );
      }
      // in case it's a critical error: return immediately!
      return CriticalError;
    case KMFilterAction::ErrorButGoOn:
      if ( FilterLog::instance()->isLogging() ) {
        QString logText = QString( "%1" )
          .arg( i18n( "A problem was found while applying this action." ) );
        FilterLog::instance()->add( logText, FilterLog::appliedAction );
      }
    default:
      break;
    }
  }

  if ( status == NoResult ) // No filters matched, keep copy of message
    status = GoOn;

  stopIt = stopProcessingHere();

  return status;
}

bool KMFilter::requiresBody( KMMsgBase* msg )
{
  if (pattern() && pattern()->requiresBody())
    return true; // no pattern means always matches?
  QPtrListIterator<KMFilterAction> it( *actions() );
  for ( it.toFirst() ; it.current() ; ++it )
    if ((*it)->requiresBody( msg ))
      return true;
  return false;
}

/** No descriptions */
// only for bPopFilter
void KMFilter::setAction(const KMPopFilterAction aAction)
{
  mAction = aAction;
}

// only for bPopFilter
KMPopFilterAction KMFilter::action()
{
  return mAction;
}

// only for !bPopFilter
bool KMFilter::folderRemoved( KMFolder* aFolder, KMFolder* aNewFolder )
{
  bool rem = false;

  QPtrListIterator<KMFilterAction> it( mActions );
  for ( it.toFirst() ; it.current() ; ++it )
    if ( (*it)->folderRemoved( aFolder, aNewFolder ) )
      rem = true;

  return rem;
}

void KMFilter::setApplyOnAccount( uint id, bool aApply )
{
  if (aApply && !mAccounts.contains( id )) {
    mAccounts.append( id );
  } else if (!aApply && mAccounts.contains( id )) {
    mAccounts.remove( id );
  }
}

bool KMFilter::applyOnAccount( uint id ) const
{
  if ( applicability() == All )
    return true;
  if ( applicability() == ButImap ) {
    KMAccount *account = kmkernel->acctMgr()->find( id );
    bool result =  account && !dynamic_cast<KMAcctImap*>(account);
    return result;
  }
  if ( applicability() == Checked )
    return mAccounts.contains( id );

  return false;
}

//-----------------------------------------------------------------------------
void KMFilter::readConfig(KConfig* config)
{
  // MKSearchPattern::readConfig ensures
  // that the pattern is purified.
  mPattern.readConfig(config);

  if (bPopFilter) {
    // get the action description...
    QString action = config->readEntry( "action" );
    if ( action == "down" )
      mAction = Down;
    else if ( action == "later" )
      mAction = Later;
    else if ( action == "delete" )
      mAction = Delete;
    else
      mAction = NoAction;
  }
  else {
    QStringList sets = config->readListEntry("apply-on");
    if ( sets.isEmpty() && !config->hasKey("apply-on") ) {
      bApplyOnOutbound = false;
      bApplyOnInbound = true;
      bApplyOnExplicit = true;
      mApplicability = ButImap;
    } else {
      bApplyOnInbound = bool(sets.contains("check-mail"));
      bApplyOnOutbound = bool(sets.contains("send-mail"));
      bApplyOnExplicit = bool(sets.contains("manual-filtering"));
      mApplicability = (AccountType)config->readNumEntry( "Applicability", ButImap );
    }

    bStopProcessingHere = config->readBoolEntry("StopProcessingHere", true);
    bConfigureShortcut = config->readBoolEntry("ConfigureShortcut", false);
    QString shortcut( config->readEntry( "Shortcut" ) );
    if ( !shortcut.isEmpty() ) {
      KShortcut sc( shortcut );
      setShortcut( sc );
    }
    bConfigureToolbar = config->readBoolEntry("ConfigureToolbar", false);
    bConfigureToolbar = bConfigureToolbar && bConfigureShortcut;
    mIcon = config->readEntry( "Icon", "gear" );
    bAutoNaming = config->readBoolEntry("AutomaticName", false);

    int i, numActions;
    QString actName, argsName;

    mActions.clear();

    numActions = config->readNumEntry("actions",0);
    if (numActions > FILTER_MAX_ACTIONS) {
      numActions = FILTER_MAX_ACTIONS ;
      KMessageBox::information( 0, i18n("<qt>Too many filter actions in filter rule %1.</qt>").arg( mPattern.name() ) );
    }

    for ( i=0 ; i < numActions ; i++ ) {
      actName.sprintf("action-name-%d", i);
      argsName.sprintf("action-args-%d", i);
      // get the action description...
      KMFilterActionDesc *desc = (*kmkernel->filterActionDict())[ config->readEntry( actName ) ];
      if ( desc ) {
        //...create an instance...
        KMFilterAction *fa = desc->create();
        if ( fa ) {
          //...load it with it's parameter...
          fa->argsFromString( config->readEntry( argsName ) );
          //...check if it's emoty and...
          if ( !fa->isEmpty() )
            //...append it if it's not and...
            mActions.append( fa );
          else
            //...delete is else.
            delete fa;
        }
      } else
        KMessageBox::information( 0 /* app-global modal dialog box */,
                                  i18n("<qt>Unknown filter action %1
in filter rule %2.
Ignoring it.</qt>")
                                       .arg( config->readEntry( actName ) ).arg( mPattern.name() ) );
    }

    mAccounts = config->readIntListEntry( "accounts-set" );
  }
}

void KMFilter::writeConfig(KConfig* config) const
{
  mPattern.writeConfig(config);

  if (bPopFilter) {
    switch ( mAction ) {
    case Down:
      config->writeEntry( "action", "down" );
      break;
    case Later:
      config->writeEntry( "action", "later" );
      break;
    case Delete:
      config->writeEntry( "action", "delete" );
      break;
    default:
      config->writeEntry( "action", "" );
    }
  } else {
    QStringList sets;
    if ( bApplyOnInbound )
      sets.append( "check-mail" );
    if ( bApplyOnOutbound )
      sets.append( "send-mail" );
    if ( bApplyOnExplicit )
      sets.append( "manual-filtering" );
    config->writeEntry( "apply-on", sets );

    config->writeEntry( "StopProcessingHere", bStopProcessingHere );
    config->writeEntry( "ConfigureShortcut", bConfigureShortcut );
    if ( !mShortcut.isNull() )
      config->writeEntry( "Shortcut", mShortcut.toString() );
    config->writeEntry( "ConfigureToolbar", bConfigureToolbar );
    config->writeEntry( "Icon", mIcon );
    config->writeEntry( "AutomaticName", bAutoNaming );
    config->writeEntry( "Applicability", mApplicability );

    QString key;
    int i;

    QPtrListIterator<KMFilterAction> it( mActions );
    for ( i=0, it.toFirst() ; it.current() ; ++it, ++i ) {
      config->writeEntry( key.sprintf("action-name-%d", i),
                          (*it)->name() );
      config->writeEntry( key.sprintf("action-args-%d", i),
                          (*it)->argsAsString() );
    }
    config->writeEntry( "actions", i );
    config->writeEntry( "accounts-set", mAccounts );
  }
}

void KMFilter::purify()
{
  mPattern.purify();

  if (!bPopFilter) {
    QPtrListIterator<KMFilterAction> it( mActions );
    it.toLast();
    while ( it.current() )
      if ( (*it)->isEmpty() )
        mActions.remove ( (*it) );
      else
        --it;

    // Remove invalid accounts from mAccounts - just to be tidy
    QValueListConstIterator<int> it2 = mAccounts.begin();
    while ( it2 != mAccounts.end() ) {
      if ( !kmkernel->acctMgr()->find( *it2 ) )
         mAccounts.remove( *it2 );
      else
         ++it2;
    }
  }
}

bool KMFilter::isEmpty() const
{
  if (bPopFilter)
    return mPattern.isEmpty();
  else
    return mPattern.isEmpty() && mActions.isEmpty() && mAccounts.isEmpty();
}

#ifndef NDEBUG
const QString KMFilter::asString() const
{
  QString result;

  result += mPattern.asString();

  if (bPopFilter){
    result += "    action: ";
    result += mAction;
    result += "\n";
  }
  else {
    QPtrListIterator<KMFilterAction> it( mActions );
    for ( it.toFirst() ; it.current() ; ++it ) {
      result += "    action: ";
      result += (*it)->label();
      result += " ";
      result += (*it)->argsAsString();
      result += "\n";
    }
    result += "This filter belongs to the following sets:";
    if ( bApplyOnInbound )
      result += " Inbound";
    if ( bApplyOnOutbound )
      result += " Outbound";
    if ( bApplyOnExplicit )
      result += " Explicit";
    result += "\n";
    if ( bApplyOnInbound && mApplicability == All ) {
      result += "This filter applies to all accounts.\n";
    } else if ( bApplyOnInbound && mApplicability == ButImap ) {
      result += "This filter applies to all but online IMAP accounts.\n";
    } else if ( bApplyOnInbound ) {
      QValueListConstIterator<int> it2;
      result += "This filter applies to the following accounts:";
      if ( mAccounts.isEmpty() )
        result += " None";
      else for ( it2 = mAccounts.begin() ; it2 != mAccounts.end() ; ++it2 )
        if ( kmkernel->acctMgr()->find( *it2 ) )
          result += " " + kmkernel->acctMgr()->find( *it2 )->name();
      result += "\n";
    }
    if ( bStopProcessingHere )
      result += "If it matches, processing stops at this filter.\n";
  }
  return result;
}
#endif
<commit_msg>Fixes the following bug: When an account is removed, the filters related to it get stuck in an infinite loop when KMail is restarted, preventing KMail from starting.<commit_after>/* -*- mode: C++; c-file-style: "gnu" -*-
 * kmail: KDE mail client
 * Copyright (c) 1996-1998 Stefan Taferner <taferner@kde.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include "kmfilter.h"
#include "kmkernel.h"
#include "accountmanager.h"
using KMail::AccountManager;
#include "kmacctimap.h"
#include "kmfilteraction.h"
#include "kmglobal.h"
#include "filterlog.h"
using KMail::FilterLog;

#include <klocale.h>
#include <kmessagebox.h>
#include <kdebug.h>
#include <kconfig.h>

#include <assert.h>

KMFilter::KMFilter( KConfig* aConfig, bool popFilter )
  : bPopFilter(popFilter)
{
  if (!bPopFilter)
    mActions.setAutoDelete( true );

  if ( aConfig )
    readConfig( aConfig );
  else if ( bPopFilter )
    mAction = Down;
  else {
    bApplyOnInbound = true;
    bApplyOnOutbound = false;
    bApplyOnExplicit = true;
    bStopProcessingHere = true;
    bConfigureShortcut = false;
    bConfigureToolbar = false;
    bAutoNaming = true;
    mApplicability = All;
  }
}

KMFilter::KMFilter( const KMFilter & aFilter )
{
  bPopFilter = aFilter.isPopFilter();

  if ( !bPopFilter )
    mActions.setAutoDelete( true );

  mPattern = aFilter.mPattern;

  if ( bPopFilter ){
    mAction = aFilter.mAction;
  } else {
    bApplyOnInbound = aFilter.applyOnInbound();
    bApplyOnOutbound = aFilter.applyOnOutbound();
    bApplyOnExplicit = aFilter.applyOnExplicit();
    bStopProcessingHere = aFilter.stopProcessingHere();
    bConfigureShortcut = aFilter.configureShortcut();
    bConfigureToolbar = aFilter.configureToolbar();
    mApplicability = aFilter.applicability();
    mIcon = aFilter.icon();
    mShortcut = aFilter.shortcut();

    QPtrListIterator<KMFilterAction> it( aFilter.mActions );
    for ( it.toFirst() ; it.current() ; ++it ) {
      KMFilterActionDesc *desc = (*kmkernel->filterActionDict())[ (*it)->name() ];
      if ( desc ) {
        KMFilterAction *f = desc->create();
        if ( f ) {
          f->argsFromString( (*it)->argsAsString() );
          mActions.append( f );
        }
      }
    }

    mAccounts.clear();
    QValueListConstIterator<int> it2;
    for ( it2 = aFilter.mAccounts.begin() ; it2 != aFilter.mAccounts.end() ; ++it2 )
      mAccounts.append( *it2 );
  }
}

// only for !bPopFilter
KMFilter::ReturnCode KMFilter::execActions( KMMessage* msg, bool& stopIt ) const
{
  ReturnCode status = NoResult;

  QPtrListIterator<KMFilterAction> it( mActions );
  for ( it.toFirst() ; it.current() ; ++it ) {

    if ( FilterLog::instance()->isLogging() ) {
      QString logText( i18n( "Applying filter action: %1" )
                       .arg( (*it)->displayString() ) );
      FilterLog::instance()->add( logText, FilterLog::appliedAction );
    }

    KMFilterAction::ReturnCode result = (*it)->process( msg );

    switch ( result ) {
    case KMFilterAction::CriticalError:
      if ( FilterLog::instance()->isLogging() ) {
        QString logText = QString( "%1" )
          .arg( i18n( "A critical error occurred. Processing stops here." ) );
        FilterLog::instance()->add( logText, FilterLog::appliedAction );
      }
      // in case it's a critical error: return immediately!
      return CriticalError;
    case KMFilterAction::ErrorButGoOn:
      if ( FilterLog::instance()->isLogging() ) {
        QString logText = QString( "%1" )
          .arg( i18n( "A problem was found while applying this action." ) );
        FilterLog::instance()->add( logText, FilterLog::appliedAction );
      }
    default:
      break;
    }
  }

  if ( status == NoResult ) // No filters matched, keep copy of message
    status = GoOn;

  stopIt = stopProcessingHere();

  return status;
}

bool KMFilter::requiresBody( KMMsgBase* msg )
{
  if (pattern() && pattern()->requiresBody())
    return true; // no pattern means always matches?
  QPtrListIterator<KMFilterAction> it( *actions() );
  for ( it.toFirst() ; it.current() ; ++it )
    if ((*it)->requiresBody( msg ))
      return true;
  return false;
}

/** No descriptions */
// only for bPopFilter
void KMFilter::setAction(const KMPopFilterAction aAction)
{
  mAction = aAction;
}

// only for bPopFilter
KMPopFilterAction KMFilter::action()
{
  return mAction;
}

// only for !bPopFilter
bool KMFilter::folderRemoved( KMFolder* aFolder, KMFolder* aNewFolder )
{
  bool rem = false;

  QPtrListIterator<KMFilterAction> it( mActions );
  for ( it.toFirst() ; it.current() ; ++it )
    if ( (*it)->folderRemoved( aFolder, aNewFolder ) )
      rem = true;

  return rem;
}

void KMFilter::setApplyOnAccount( uint id, bool aApply )
{
  if (aApply && !mAccounts.contains( id )) {
    mAccounts.append( id );
  } else if (!aApply && mAccounts.contains( id )) {
    mAccounts.remove( id );
  }
}

bool KMFilter::applyOnAccount( uint id ) const
{
  if ( applicability() == All )
    return true;
  if ( applicability() == ButImap ) {
    KMAccount *account = kmkernel->acctMgr()->find( id );
    bool result =  account && !dynamic_cast<KMAcctImap*>(account);
    return result;
  }
  if ( applicability() == Checked )
    return mAccounts.contains( id );

  return false;
}

//-----------------------------------------------------------------------------
void KMFilter::readConfig(KConfig* config)
{
  // MKSearchPattern::readConfig ensures
  // that the pattern is purified.
  mPattern.readConfig(config);

  if (bPopFilter) {
    // get the action description...
    QString action = config->readEntry( "action" );
    if ( action == "down" )
      mAction = Down;
    else if ( action == "later" )
      mAction = Later;
    else if ( action == "delete" )
      mAction = Delete;
    else
      mAction = NoAction;
  }
  else {
    QStringList sets = config->readListEntry("apply-on");
    if ( sets.isEmpty() && !config->hasKey("apply-on") ) {
      bApplyOnOutbound = false;
      bApplyOnInbound = true;
      bApplyOnExplicit = true;
      mApplicability = ButImap;
    } else {
      bApplyOnInbound = bool(sets.contains("check-mail"));
      bApplyOnOutbound = bool(sets.contains("send-mail"));
      bApplyOnExplicit = bool(sets.contains("manual-filtering"));
      mApplicability = (AccountType)config->readNumEntry( "Applicability", ButImap );
    }

    bStopProcessingHere = config->readBoolEntry("StopProcessingHere", true);
    bConfigureShortcut = config->readBoolEntry("ConfigureShortcut", false);
    QString shortcut( config->readEntry( "Shortcut" ) );
    if ( !shortcut.isEmpty() ) {
      KShortcut sc( shortcut );
      setShortcut( sc );
    }
    bConfigureToolbar = config->readBoolEntry("ConfigureToolbar", false);
    bConfigureToolbar = bConfigureToolbar && bConfigureShortcut;
    mIcon = config->readEntry( "Icon", "gear" );
    bAutoNaming = config->readBoolEntry("AutomaticName", false);

    int i, numActions;
    QString actName, argsName;

    mActions.clear();

    numActions = config->readNumEntry("actions",0);
    if (numActions > FILTER_MAX_ACTIONS) {
      numActions = FILTER_MAX_ACTIONS ;
      KMessageBox::information( 0, i18n("<qt>Too many filter actions in filter rule %1.</qt>").arg( mPattern.name() ) );
    }

    for ( i=0 ; i < numActions ; i++ ) {
      actName.sprintf("action-name-%d", i);
      argsName.sprintf("action-args-%d", i);
      // get the action description...
      KMFilterActionDesc *desc = (*kmkernel->filterActionDict())[ config->readEntry( actName ) ];
      if ( desc ) {
        //...create an instance...
        KMFilterAction *fa = desc->create();
        if ( fa ) {
          //...load it with it's parameter...
          fa->argsFromString( config->readEntry( argsName ) );
          //...check if it's emoty and...
          if ( !fa->isEmpty() )
            //...append it if it's not and...
            mActions.append( fa );
          else
            //...delete is else.
            delete fa;
        }
      } else
        KMessageBox::information( 0 /* app-global modal dialog box */,
                                  i18n("<qt>Unknown filter action %1
in filter rule %2.
Ignoring it.</qt>")
                                       .arg( config->readEntry( actName ) ).arg( mPattern.name() ) );
    }

    mAccounts = config->readIntListEntry( "accounts-set" );
  }
}

void KMFilter::writeConfig(KConfig* config) const
{
  mPattern.writeConfig(config);

  if (bPopFilter) {
    switch ( mAction ) {
    case Down:
      config->writeEntry( "action", "down" );
      break;
    case Later:
      config->writeEntry( "action", "later" );
      break;
    case Delete:
      config->writeEntry( "action", "delete" );
      break;
    default:
      config->writeEntry( "action", "" );
    }
  } else {
    QStringList sets;
    if ( bApplyOnInbound )
      sets.append( "check-mail" );
    if ( bApplyOnOutbound )
      sets.append( "send-mail" );
    if ( bApplyOnExplicit )
      sets.append( "manual-filtering" );
    config->writeEntry( "apply-on", sets );

    config->writeEntry( "StopProcessingHere", bStopProcessingHere );
    config->writeEntry( "ConfigureShortcut", bConfigureShortcut );
    if ( !mShortcut.isNull() )
      config->writeEntry( "Shortcut", mShortcut.toString() );
    config->writeEntry( "ConfigureToolbar", bConfigureToolbar );
    config->writeEntry( "Icon", mIcon );
    config->writeEntry( "AutomaticName", bAutoNaming );
    config->writeEntry( "Applicability", mApplicability );

    QString key;
    int i;

    QPtrListIterator<KMFilterAction> it( mActions );
    for ( i=0, it.toFirst() ; it.current() ; ++it, ++i ) {
      config->writeEntry( key.sprintf("action-name-%d", i),
                          (*it)->name() );
      config->writeEntry( key.sprintf("action-args-%d", i),
                          (*it)->argsAsString() );
    }
    config->writeEntry( "actions", i );
    config->writeEntry( "accounts-set", mAccounts );
  }
}

void KMFilter::purify()
{
  mPattern.purify();

  if (!bPopFilter) {
    QPtrListIterator<KMFilterAction> it( mActions );
    it.toLast();
    while ( it.current() )
      if ( (*it)->isEmpty() )
        mActions.remove ( (*it) );
      else
        --it;

    // Remove invalid accounts from mAccounts - just to be tidy
    QValueListIterator<int> it2 = mAccounts.begin();
    while ( it2 != mAccounts.end() ) {
      if ( !kmkernel->acctMgr()->find( *it2 ) )
         it2 = mAccounts.remove( it2 );
      else
         ++it2;
    }
  }
}

bool KMFilter::isEmpty() const
{
  if (bPopFilter)
    return mPattern.isEmpty();
  else
    return mPattern.isEmpty() && mActions.isEmpty() && mAccounts.isEmpty();
}

#ifndef NDEBUG
const QString KMFilter::asString() const
{
  QString result;

  result += mPattern.asString();

  if (bPopFilter){
    result += "    action: ";
    result += mAction;
    result += "\n";
  }
  else {
    QPtrListIterator<KMFilterAction> it( mActions );
    for ( it.toFirst() ; it.current() ; ++it ) {
      result += "    action: ";
      result += (*it)->label();
      result += " ";
      result += (*it)->argsAsString();
      result += "\n";
    }
    result += "This filter belongs to the following sets:";
    if ( bApplyOnInbound )
      result += " Inbound";
    if ( bApplyOnOutbound )
      result += " Outbound";
    if ( bApplyOnExplicit )
      result += " Explicit";
    result += "\n";
    if ( bApplyOnInbound && mApplicability == All ) {
      result += "This filter applies to all accounts.\n";
    } else if ( bApplyOnInbound && mApplicability == ButImap ) {
      result += "This filter applies to all but online IMAP accounts.\n";
    } else if ( bApplyOnInbound ) {
      QValueListConstIterator<int> it2;
      result += "This filter applies to the following accounts:";
      if ( mAccounts.isEmpty() )
        result += " None";
      else for ( it2 = mAccounts.begin() ; it2 != mAccounts.end() ; ++it2 )
        if ( kmkernel->acctMgr()->find( *it2 ) )
          result += " " + kmkernel->acctMgr()->find( *it2 )->name();
      result += "\n";
    }
    if ( bStopProcessingHere )
      result += "If it matches, processing stops at this filter.\n";
  }
  return result;
}
#endif
<|endoftext|>


<commit_before>/******************************************************************************
 * This file is part of the Gluon Development Platform
 * Copyright (C) 2011 Laszlo Papp <djszapi@archlinux.us>
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "gamesoverlay.h"
#include "loginform.h"
#include "views/gamesview.h"

GamesOverlay::GamesOverlay( QWidget* parent, Qt::WindowFlags wFlags )
    : QWidget( parent, wFlags )
    , m_view( new QListView( this ) )
    , m_model( new ListModel( m_view ) )
    , m_gamesView( new GamesView( this ) )
    , m_loginForm( new LoginForm( this ) )
{
    connect( m_gamesView, SIGNAL( gameToPlaySelected( QModelIndex ) ), SIGNAL( gameToPlaySelected( QModelIndex ) ) );
    connect( m_gamesView, SIGNAL( gameSelected( QModelIndex ) ), SIGNAL( gameSelected( QModelIndex ) ) );

    // QListView* view = new QListView( base );

    // m_tabWidget->addTab( m_gamesView, KIcon( "applications-games" ), i18n( "Installed" ) );

    // QLabel* m_tempLabel = new QLabel( this );
    // m_tempLabel->setText( i18n( "Coming Soon!" ) );

    m_view->setModel(m_model);
    m_model->appendPair(qMakePair(QString("Installed"), new KIcon( "applications-games" )));
    m_model->appendPair(qMakePair(QString("Available"), new KIcon( "get-hot-new-stuff" )));
    m_model->appendPair(qMakePair(QString("Login"), new KIcon( "network-connect" )));
    m_model->appendPair(qMakePair(QString("Community"), new KIcon( "" )));

    // QGridLayout* gridLayout = static_cast<QGridLayout*>( layout() );
    QGridLayout* gridLayout = new QGridLayout( this );
    gridLayout->addWidget( m_view );
    setLayout( gridLayout );
}

GamesView* GamesOverlay::gamesView()
{
    return m_gamesView;
}
<commit_msg>KDE Extended Player: Add a rightGridLayout to the gamesoverlay layout.<commit_after>/******************************************************************************
 * This file is part of the Gluon Development Platform
 * Copyright (C) 2011 Laszlo Papp <djszapi@archlinux.us>
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "gamesoverlay.h"
#include "loginform.h"
#include "views/gamesview.h"

GamesOverlay::GamesOverlay( QWidget* parent, Qt::WindowFlags wFlags )
    : QWidget( parent, wFlags )
    , m_view( new QListView( this ) )
    , m_model( new ListModel( m_view ) )
    // , m_gamesView( new GamesView( this ) )
    , m_loginForm( new LoginForm( this ) )
{
    // connect( m_gamesView, SIGNAL( gameToPlaySelected( QModelIndex ) ), SIGNAL( gameToPlaySelected( QModelIndex ) ) );
    // connect( m_gamesView, SIGNAL( gameSelected( QModelIndex ) ), SIGNAL( gameSelected( QModelIndex ) ) );

    // QListView* view = new QListView( base );

    // m_tabWidget->addTab( m_gamesView, KIcon( "applications-games" ), i18n( "Installed" ) );

    // QLabel* m_tempLabel = new QLabel( this );
    // m_tempLabel->setText( i18n( "Coming Soon!" ) );

    m_view->setModel(m_model);
    m_model->appendPair(qMakePair(QString("Installed"), new KIcon( "applications-games" )));
    m_model->appendPair(qMakePair(QString("Available"), new KIcon( "get-hot-new-stuff" )));
    m_model->appendPair(qMakePair(QString("Login"), new KIcon( "network-connect" )));
    m_model->appendPair(qMakePair(QString("Community"), new KIcon( "" )));

    // QGridLayout* gridLayout = static_cast<QGridLayout*>( layout() );
    QGridLayout* gridLayout = new QGridLayout( this );
    gridLayout->addWidget( m_view, 0, 0 );
    gridLayout->setColumnStretch( 0, 1 );

    QGridLayout* rightGridLayout = new QGridLayout( this );
    gridLayout->addLayout( rightGridLayout, 0, 1 );
    gridLayout->setColumnStretch( 1, 3 );
    setLayout( gridLayout );
}

GamesView* GamesOverlay::gamesView()
{
    return m_gamesView;
}
<|endoftext|>


<commit_before>//
//  AliEveDataSourceHLTZMQ
//
//  blame: Mikolaj Krzewicki, mikolaj.krzewicki@cern.ch
//
//

#include "AliEveDataSourceHLTZMQ.h"

#include "AliEveConfigManager.h"
#include "AliCDBManager.h"
#include "AliCDBStorage.h"
#include "AliGRPPreprocessor.h"
#include <TEnv.h>
#include <TInterpreter.h>
#include <iostream>

#include "AliHLTComponent.h"
#include "AliHLTMessage.h"

#ifdef ZMQ
#include "zmq.h"
#endif

using namespace std;

AliEveDataSourceHLTZMQ::AliEveDataSourceHLTZMQ(bool storageManager) :
    AliEveDataSource("HLT"),
    fEventListenerThreadHLT(0),
    fZMQContext(NULL),
    fZMQeventQueue(NULL),
    fHLTPublisherAddress("tcp://localhost:60201")
{
  //ctor
  Init();
}

void AliEveDataSourceHLTZMQ::Init()
{
#ifdef ZMQ
  //get the address of the HLT proxy from the environment
  if (gSystem->Getenv("HLT_ZMQ_proxy"))
    fHLTPublisherAddress=gSystem->Getenv("HLT_ZMQ_proxy");
  //single ZMQ context for inter thread comm. etc.
  if (!fZMQContext) fZMQContext = zmq_ctx_new();
  //single ZMQ socket for gathering the events form various listening threads
  //must be bound before threads can connect
  if (! fZMQeventQueue)
  {
    fZMQeventQueue = zmq_socket(fZMQContext, ZMQ_PULL);
    zmq_bind(fZMQeventQueue, "inproc://fCurrentEvent");
  }

  AliInfo("Starting HLT subscriber thread.");
  if(fEventListenerThreadHLT)
  {
    fEventListenerThreadHLT->Join();
    fEventListenerThreadHLT->Kill();
    delete fEventListenerThreadHLT;
    AliInfo("HLT listener thread killed and deleted");
  }
  fEventListenerThreadHLT = new TThread("fEventListenerThreadHLT",DispatchEventListenerHLT,(void*)this);
  fEventListenerThreadHLT->Run();
#endif
}

AliEveDataSourceHLTZMQ::~AliEveDataSourceHLTZMQ()
{
#ifdef ZMQ
  if (fZMQeventQueue)
  {
    int lingerValue = 0;
    int rc = zmq_setsockopt(fZMQeventQueue, ZMQ_LINGER, &lingerValue, sizeof(int));
    if (rc<0) printf("error setting linger on fZMQeventQueue\n");
    rc = zmq_close(fZMQeventQueue);
    if (rc<0) printf("error closing socket fZMQeventQueue\n");
  }

  printf("trying to destroy fZMQContext\n");
  if (fZMQContext) zmq_ctx_destroy(fZMQContext);
  printf("destroyed fZMQContext\n");
#endif

  if(fEventListenerThreadHLT)
  {
    fEventListenerThreadHLT->Join();
    fEventListenerThreadHLT->Kill();
    delete fEventListenerThreadHLT;
    cout<<"HLT listener thread killed and deleted"<<endl;
  }

}

void AliEveDataSourceHLTZMQ::PullEventFromHLT()
{
#ifdef ZMQ
  int rc = 0;

  if (!fZMQContext) return;

  //connection to the HLT data
  void* listenerSocket = zmq_socket(fZMQContext, ZMQ_SUB);
  if (!listenerSocket) {return;}
  printf("connecting to ZMQ socket: %s\n", fHLTPublisherAddress.Data());
  rc = zmq_connect(listenerSocket, fHLTPublisherAddress.Data());
  rc = zmq_setsockopt (listenerSocket, ZMQ_SUBSCRIBE, NULL, 0);
  if (rc < 0) {return;}

  //internal publisher
  void* internalPublisher = zmq_socket(fZMQContext, ZMQ_PUSH);
  if (!internalPublisher) {return;}
  rc = zmq_connect(internalPublisher, "inproc://fCurrentEvent");
  if (rc < 0) {return;}

  //create a default selection of any data:
  char requestedTopic[kAliHLTComponentDataTypeTopicSize+1]; memset(&requestedTopic, 0, sizeof(requestedTopic));
  memset(&requestedTopic, '*', kAliHLTComponentDataTypeTopicSize);
  strncpy(requestedTopic, "ALIESDV0HLT**************", kAliHLTComponentDataTypeTopicSize);
  char requestedTopic1[kAliHLTComponentDataTypeTopicSize+1]; memset(&requestedTopic1, 0, sizeof(requestedTopic1));
  memset(&requestedTopic1, '*', kAliHLTComponentDataTypeTopicSize);
  strncpy(requestedTopic1, "FLATESD**************", kAliHLTComponentDataTypeTopicSize);

  Bool_t done=false;
  while (!done)
  {
    int more = 0;
    size_t more_size = sizeof more;
    do
    {
      //here the HLT data comes in
      //receive the topic
      char receivedTopic[kAliHLTComponentDataTypeTopicSize+1]; memset(&receivedTopic, 0, sizeof(receivedTopic));
      int receivedTopicSize = zmq_recv(listenerSocket, &receivedTopic, sizeof(receivedTopic), 0);
      if (receivedTopicSize < 0 && errno==ETERM) {AliInfo("listenerSocket received ETERM, exiting main loop"); done=true; break;}

      //reive the message if there is any
      zmq_msg_t message;
      rc = zmq_msg_init(&message);
      rc = zmq_getsockopt(listenerSocket, ZMQ_RCVMORE, &more, &more_size);
      if (more)
      {
        rc = zmq_msg_recv(&message, listenerSocket, 0);
        if (rc < 0 && errno==ETERM) { zmq_msg_close(&message); done=true; break; }
      }
      rc = zmq_getsockopt(listenerSocket, ZMQ_RCVMORE, &more, &more_size);

      //after receiving a single part (topic+message) publish it internally
      //in general this will be an HLT ESD.
      //do check first if this is what we wanted
      bool isSelected = Topicncmp(requestedTopic, receivedTopic, kAliHLTComponentDataTypeTopicSize, receivedTopicSize) ||
                        Topicncmp(requestedTopic1, receivedTopic, kAliHLTComponentDataTypeTopicSize, receivedTopicSize);

      if (!isSelected)
      {
        //clean up the memory and continue
        //printf("  dropped %s\n",receivedTopic);
        zmq_msg_close(&message);
        continue;
      }

      //publish the data for further use
      rc = -1;
      //printf("pushing %s\n", receivedTopic);
      rc = zmq_send(internalPublisher, &receivedTopic, receivedTopicSize, ZMQ_SNDMORE);
      rc = zmq_msg_send(&message, internalPublisher, 0);
      if (rc < 0) zmq_msg_close(&message);

    } while (more != 0);
  }
  //cleanly exit the thread
  int lingerValue = 10;
  rc = zmq_setsockopt(listenerSocket, ZMQ_LINGER, &lingerValue, sizeof(lingerValue));
  if (rc<0) printf("error setting linger on listenerSocket, errno: %i\n", errno);
  rc = zmq_setsockopt(internalPublisher, ZMQ_LINGER, &lingerValue, sizeof(lingerValue));
  if (rc<0) printf("error setting linger on internalPublisher, errno: %i\n",errno);
  rc = zmq_close(listenerSocket);
  if (rc<0) printf("error closing listenerSocket, errno: %i\n", errno);
  rc = zmq_close(internalPublisher);
  if (rc<0) printf("error closing internalPublisher, errno: %i\n", errno);
#endif
}

void AliEveDataSourceHLTZMQ::InitOCDB(int runNo)
{
    AliCDBManager* cdb = AliCDBManager::Instance();
  if (cdb->IsDefaultStorageSet() == kTRUE)
  {
    AliInfo(Form("CDB already set - using the old storage:  '%s'", cdb->GetDefaultStorage()->GetURI().Data()));
    return;
  }
    if (runNo!=AliEveEventManager::GetMaster()->GetCurrentRun()){
        AliEveEventManager::GetMaster()->SetCurrentRun(runNo);
      cdb->SetRun(runNo);
    }
}

void AliEveDataSourceHLTZMQ::GotoEvent(Int_t /*event*/)
{
    NextEvent();
    return;
}

void AliEveDataSourceHLTZMQ::NextEvent()
{
    static const TEveException kEH("AliEveDataSourceHLTZMQ::NextEvent ");
  //read event from queue

#ifdef ZMQ
  //init some stuff
  int rc = 0;
  AliESDEvent* esdObject = NULL;
  char topic[kAliHLTComponentDataTypeTopicSize+1]; memset(topic, 0, sizeof(topic));
  memset(topic, 0, kAliHLTComponentDataTypeTopicSize);
  zmq_msg_t message;
  rc = zmq_msg_init(&message);
  int64_t more = 0;
  size_t more_size = sizeof(more);

  //try to receive a new topic+message from the queue
  int topicSize = zmq_recv(fZMQeventQueue, &topic, kAliHLTComponentDataTypeTopicSize, ZMQ_DONTWAIT);
  int errnoTopic = errno;
  rc = zmq_getsockopt(fZMQeventQueue, ZMQ_RCVMORE, &more, &more_size);
  if (more) rc = zmq_msg_recv(&message, fZMQeventQueue, ZMQ_DONTWAIT);

  //decode the message into an AliESDEvent,
  //for HLT messages AliHLTMessage needs to be used
  if( topicSize > 0 /*&& errnoTopic != EAGAIN*/ && zmq_msg_size(&message) > 0 )
  {
    if (Topicncmp(topic, "ALIESDV0HLT", topicSize, 11))
    {
      printf("trying to decode %s with AliHLTMessage\n", topic);
      AliHLTMessage msg(zmq_msg_data(&message), zmq_msg_size(&message));
      TClass* objclass = msg.GetClass();
      esdObject = static_cast<AliESDEvent*>(msg.ReadObject(AliESDEvent::Class()));
    }
    else if (Topicncmp(topic, "ALIESDV0POR", topicSize, 11))
    {
      printf("trying to decode %s with TBufferFile\n", topic);
      TBufferFile *mess = new TBufferFile(TBuffer::kRead,
          zmq_msg_size(&message)+sizeof(UInt_t),
          zmq_msg_data(&message));
      mess->InitMap();
      mess->ReadClass();// get first the class stored in message
      mess->SetBufferOffset(sizeof(UInt_t) + sizeof(kMESS_OBJECT));
      mess->ResetMap();
      esdObject = (AliESDEvent*)(mess->ReadObjectAny(AliESDEvent::Class()));
    }
    else
    {
      printf("Don't know what to do with %s\n",topic);
    }
  }
  if (esdObject)
  {
    printf("setting new event\n");
    esdObject->GetStdContent();
    int runNumber = esdObject->GetRunNumber();
    InitOCDB(runNumber);

    printf("deleting current data\n");
    //replace the ESD
    fCurrentData.Clear();
    fCurrentData.fESD = esdObject;
  }
  else
  {
    cout<<"No new event is avaliable."<<endl;
  }
  zmq_msg_close(&message);
#endif
}

void AliEveDataSourceHLTZMQ::SetCdbUri(const TString& cdb)
{
    // Set path to CDB, there is no default.
    if ( ! cdb.IsNull()) fgCdbUri = cdb;
    AliCDBManager* cdbManager = AliCDBManager::Instance();
    cdbManager->SetDefaultStorage(cdb);
}

<commit_msg>call AfterNewEventLoaded() to notify the event man<commit_after>//
//  AliEveDataSourceHLTZMQ
//
//  blame: Mikolaj Krzewicki, mikolaj.krzewicki@cern.ch
//
//

#include "AliEveDataSourceHLTZMQ.h"

#include "AliEveConfigManager.h"
#include "AliCDBManager.h"
#include "AliCDBStorage.h"
#include "AliGRPPreprocessor.h"
#include <TEnv.h>
#include <TInterpreter.h>
#include <iostream>

#include "AliHLTComponent.h"
#include "AliHLTMessage.h"

#ifdef ZMQ
#include "zmq.h"
#endif

using namespace std;

AliEveDataSourceHLTZMQ::AliEveDataSourceHLTZMQ(bool storageManager) :
    AliEveDataSource("HLT"),
    fEventListenerThreadHLT(0),
    fCurrentRun(-1),
    fZMQContext(NULL),
    fZMQeventQueue(NULL),
    fHLTPublisherAddress("tcp://localhost:60201")
{
  //ctor
  Init();
}

void AliEveDataSourceHLTZMQ::Init()
{
#ifdef ZMQ
  //get the address of the HLT proxy from the environment
  if (gSystem->Getenv("HLT_ZMQ_proxy"))
    fHLTPublisherAddress=gSystem->Getenv("HLT_ZMQ_proxy");
  //single ZMQ context for inter thread comm. etc.
  if (!fZMQContext) fZMQContext = zmq_ctx_new();
  //single ZMQ socket for gathering the events form various listening threads
  //must be bound before threads can connect
  if (! fZMQeventQueue)
  {
    fZMQeventQueue = zmq_socket(fZMQContext, ZMQ_PULL);
    zmq_bind(fZMQeventQueue, "inproc://fCurrentEvent");
  }

  AliInfo("Starting HLT subscriber thread.");
  if(fEventListenerThreadHLT)
  {
    fEventListenerThreadHLT->Join();
    fEventListenerThreadHLT->Kill();
    delete fEventListenerThreadHLT;
    AliInfo("HLT listener thread killed and deleted");
  }
  fEventListenerThreadHLT = new TThread("fEventListenerThreadHLT",DispatchEventListenerHLT,(void*)this);
  fEventListenerThreadHLT->Run();
#endif
}

AliEveDataSourceHLTZMQ::~AliEveDataSourceHLTZMQ()
{
#ifdef ZMQ
  if (fZMQeventQueue)
  {
    int lingerValue = 0;
    int rc = zmq_setsockopt(fZMQeventQueue, ZMQ_LINGER, &lingerValue, sizeof(int));
    if (rc<0) printf("error setting linger on fZMQeventQueue\n");
    rc = zmq_close(fZMQeventQueue);
    if (rc<0) printf("error closing socket fZMQeventQueue\n");
  }

  printf("trying to destroy fZMQContext\n");
  if (fZMQContext) zmq_ctx_destroy(fZMQContext);
  printf("destroyed fZMQContext\n");
#endif

  if(fEventListenerThreadHLT)
  {
    fEventListenerThreadHLT->Join();
    fEventListenerThreadHLT->Kill();
    delete fEventListenerThreadHLT;
    cout<<"HLT listener thread killed and deleted"<<endl;
  }

}

void AliEveDataSourceHLTZMQ::PullEventFromHLT()
{
#ifdef ZMQ
  int rc = 0;

  if (!fZMQContext) return;

  //connection to the HLT data
  void* listenerSocket = zmq_socket(fZMQContext, ZMQ_SUB);
  if (!listenerSocket) {return;}
  printf("connecting to ZMQ socket: %s\n", fHLTPublisherAddress.Data());
  rc = zmq_connect(listenerSocket, fHLTPublisherAddress.Data());
  rc = zmq_setsockopt (listenerSocket, ZMQ_SUBSCRIBE, NULL, 0);
  if (rc < 0) {return;}

  //internal publisher
  void* internalPublisher = zmq_socket(fZMQContext, ZMQ_PUSH);
  if (!internalPublisher) {return;}
  rc = zmq_connect(internalPublisher, "inproc://fCurrentEvent");
  if (rc < 0) {return;}

  //create a default selection of any data:
  char requestedTopic[kAliHLTComponentDataTypeTopicSize+1]; memset(&requestedTopic, 0, sizeof(requestedTopic));
  memset(&requestedTopic, '*', kAliHLTComponentDataTypeTopicSize);
  strncpy(requestedTopic, "ALIESDV0HLT**************", kAliHLTComponentDataTypeTopicSize);
  char requestedTopic1[kAliHLTComponentDataTypeTopicSize+1]; memset(&requestedTopic1, 0, sizeof(requestedTopic1));
  memset(&requestedTopic1, '*', kAliHLTComponentDataTypeTopicSize);
  strncpy(requestedTopic1, "FLATESD**************", kAliHLTComponentDataTypeTopicSize);

  Bool_t done=false;
  while (!done)
  {
    int more = 0;
    size_t more_size = sizeof more;
    do
    {
      //here the HLT data comes in
      //receive the topic
      char receivedTopic[kAliHLTComponentDataTypeTopicSize+1]; memset(&receivedTopic, 0, sizeof(receivedTopic));
      int receivedTopicSize = zmq_recv(listenerSocket, &receivedTopic, sizeof(receivedTopic), 0);
      if (receivedTopicSize < 0 && errno==ETERM) {AliInfo("listenerSocket received ETERM, exiting main loop"); done=true; break;}

      //reive the message if there is any
      zmq_msg_t message;
      rc = zmq_msg_init(&message);
      rc = zmq_getsockopt(listenerSocket, ZMQ_RCVMORE, &more, &more_size);
      if (more)
      {
        rc = zmq_msg_recv(&message, listenerSocket, 0);
        if (rc < 0 && errno==ETERM) { zmq_msg_close(&message); done=true; break; }
      }
      rc = zmq_getsockopt(listenerSocket, ZMQ_RCVMORE, &more, &more_size);

      //after receiving a single part (topic+message) publish it internally
      //in general this will be an HLT ESD.
      //do check first if this is what we wanted
      bool isSelected = Topicncmp(requestedTopic, receivedTopic, kAliHLTComponentDataTypeTopicSize, receivedTopicSize) ||
                        Topicncmp(requestedTopic1, receivedTopic, kAliHLTComponentDataTypeTopicSize, receivedTopicSize);

      if (!isSelected)
      {
        //clean up the memory and continue
        //printf("  dropped %s\n",receivedTopic);
        zmq_msg_close(&message);
        continue;
      }

      //publish the data for further use
      rc = -1;
      //printf("pushing %s\n", receivedTopic);
      rc = zmq_send(internalPublisher, &receivedTopic, receivedTopicSize, ZMQ_SNDMORE);
      rc = zmq_msg_send(&message, internalPublisher, 0);
      if (rc < 0) zmq_msg_close(&message);

    } while (more != 0);
  }
  //cleanly exit the thread
  int lingerValue = 10;
  rc = zmq_setsockopt(listenerSocket, ZMQ_LINGER, &lingerValue, sizeof(lingerValue));
  if (rc<0) printf("error setting linger on listenerSocket, errno: %i\n", errno);
  rc = zmq_setsockopt(internalPublisher, ZMQ_LINGER, &lingerValue, sizeof(lingerValue));
  if (rc<0) printf("error setting linger on internalPublisher, errno: %i\n",errno);
  rc = zmq_close(listenerSocket);
  if (rc<0) printf("error closing listenerSocket, errno: %i\n", errno);
  rc = zmq_close(internalPublisher);
  if (rc<0) printf("error closing internalPublisher, errno: %i\n", errno);
#endif
}

void AliEveDataSourceHLTZMQ::InitOCDB(int runNo)
{
  AliInfo(Form("Initializing OCDB for run: %i",runNo));
  AliCDBManager* cdb = AliCDBManager::Instance();
  if (!cdb) return;

  if (cdb->IsDefaultStorageSet() == kTRUE)
  {
    AliInfo(Form("CDB already set - using the old storage:  '%s'", cdb->GetDefaultStorage()->GetURI().Data()));
    return;
  }
  else {
    if (gSystem->Getenv("ocdbStorage")) {
    cdb->SetDefaultStorage(gSystem->Getenv("ocdbStorage"));
    if (runNo!=AliEveEventManager::GetMaster()->GetCurrentRun()){
        AliEveEventManager::GetMaster()->SetCurrentRun(runNo);
      cdb->SetRun(runNo);
    }
}

void AliEveDataSourceHLTZMQ::GotoEvent(Int_t /*event*/)
{
    NextEvent();
    return;
}

void AliEveDataSourceHLTZMQ::NextEvent()
{
    static const TEveException kEH("AliEveDataSourceHLTZMQ::NextEvent ");
  //read event from queue

#ifdef ZMQ
  //init some stuff
  int rc = 0;
  AliESDEvent* esdObject = NULL;
  char topic[kAliHLTComponentDataTypeTopicSize+1]; memset(topic, 0, sizeof(topic));
  memset(topic, 0, kAliHLTComponentDataTypeTopicSize);
  zmq_msg_t message;
  rc = zmq_msg_init(&message);
  int64_t more = 0;
  size_t more_size = sizeof(more);

  //try to receive a new topic+message from the queue
  int topicSize = zmq_recv(fZMQeventQueue, &topic, kAliHLTComponentDataTypeTopicSize, ZMQ_DONTWAIT);
  int errnoTopic = errno;
  rc = zmq_getsockopt(fZMQeventQueue, ZMQ_RCVMORE, &more, &more_size);
  if (more) rc = zmq_msg_recv(&message, fZMQeventQueue, ZMQ_DONTWAIT);

  //decode the message into an AliESDEvent,
  //for HLT messages AliHLTMessage needs to be used
  if( topicSize > 0 /*&& errnoTopic != EAGAIN*/ && zmq_msg_size(&message) > 0 )
  {
    if (Topicncmp(topic, "ALIESDV0HLT", topicSize, 11))
    {
      printf("trying to decode %s with AliHLTMessage\n", topic);
      AliHLTMessage msg(zmq_msg_data(&message), zmq_msg_size(&message));
      TClass* objclass = msg.GetClass();
      esdObject = static_cast<AliESDEvent*>(msg.ReadObject(AliESDEvent::Class()));
    }
    else if (Topicncmp(topic, "ALIESDV0POR", topicSize, 11))
    {
      printf("trying to decode %s with TBufferFile\n", topic);
      TBufferFile *mess = new TBufferFile(TBuffer::kRead,
          zmq_msg_size(&message)+sizeof(UInt_t),
          zmq_msg_data(&message));
      mess->InitMap();
      mess->ReadClass();// get first the class stored in message
      mess->SetBufferOffset(sizeof(UInt_t) + sizeof(kMESS_OBJECT));
      mess->ResetMap();
      esdObject = (AliESDEvent*)(mess->ReadObjectAny(AliESDEvent::Class()));
    }
    else
    {
      printf("Don't know what to do with %s\n",topic);
    }
  }
  if (esdObject)
  {
    printf("setting new event\n");
    esdObject->GetStdContent();
    int runNumber = esdObject->GetRunNumber();
    InitOCDB(runNumber);

    printf("deleting current data\n");
    //replace the ESD
    fCurrentData.Clear();
    fCurrentData.fESD = esdObject;

    AliEveEventManager::GetMaster()->SetHasEvent(true);
    AliEveEventManager::GetMaster()->AfterNewEventLoaded();
    //if (AliEveEventManager::GetMaster()->GetAutoLoad()) {
    //  AliEveEventManager::GetMaster()->StartAutoLoadTimer();
    //}
  }
  else
  {
    cout<<"No new event is avaliable."<<endl;
    //AliEveEventManager::GetMaster()->NoEventLoaded();
  }
  zmq_msg_close(&message);
#endif
}

void AliEveDataSourceHLTZMQ::SetCdbUri(const TString& cdb)
{
    // Set path to CDB, there is no default.
    if ( ! cdb.IsNull()) fgCdbUri = cdb;
    AliCDBManager* cdbManager = AliCDBManager::Instance();
    cdbManager->SetDefaultStorage(cdb);
}

<|endoftext|>


<commit_before>#include <vtkVersion.h>
#include <vtkBooleanOperationPolyDataFilter.h>

#include <vtkActor.h>
#include <vtkSTLReader.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>

int main(int argc, char *argv[])
{
  vtkSmartPointer<vtkPolyData> input1;
  vtkSmartPointer<vtkPolyData> input2;

  std::string operation("intersection");

  if (argc == 4)
  {
    vtkSmartPointer<vtkSTLReader> reader1 =
      vtkSmartPointer<vtkSTLReader>::New();
    reader1->SetFileName(argv[1]);
    reader1->Update();
    input1 = reader1->GetOutput();

    vtkSmartPointer<vtkSTLReader> reader2 =
      vtkSmartPointer<vtkSTLReader>::New();
    reader2->SetFileName(argv[3]);
    reader2->Update();
    input2 = reader2->GetOutput();

    operation = argv[2];
  }
  else
  {
    vtkSmartPointer<vtkSphereSource> sphereSource1 =
      vtkSmartPointer<vtkSphereSource>::New();
    sphereSource1->SetCenter(.25, 0, 0);
    sphereSource1->Update();
    input1 = sphereSource1->GetOutput();

    vtkSmartPointer<vtkSphereSource> sphereSource2 =
      vtkSmartPointer<vtkSphereSource>::New();
    sphereSource2->Update();
    input2 = sphereSource2->GetOutput();

    if (argc == 2)
    {
      operation = argv[1];
    }
  }

  vtkSmartPointer<vtkPolyDataMapper> input1Mapper =
    vtkSmartPointer<vtkPolyDataMapper>::New();
#if VTK_MAJOR_VERSION <= 5
  input1Mapper->SetInputConnection( input1->GetProducerPort() );
#else
  input1Mapper->SetInputData( input1 );
#endif
  input1Mapper->ScalarVisibilityOff();
  vtkSmartPointer<vtkActor> input1Actor =
    vtkSmartPointer<vtkActor>::New();
  input1Actor->SetMapper( input1Mapper );
  input1Actor->GetProperty()->SetColor(1,0,0);
  input1Actor->SetPosition(
    input1->GetBounds()[1]-input1->GetBounds()[0],
    0, 0);
  vtkSmartPointer<vtkPolyDataMapper> input2Mapper =
    vtkSmartPointer<vtkPolyDataMapper>::New();
#if VTK_MAJOR_VERSION <= 5
  input2Mapper->SetInputConnection( input2->GetProducerPort() );
#else
  input2Mapper->SetInputData( input2 );
#endif
  input2Mapper->ScalarVisibilityOff();
  vtkSmartPointer<vtkActor> input2Actor =
    vtkSmartPointer<vtkActor>::New();
  input2Actor->SetMapper( input2Mapper );
  input2Actor->GetProperty()->SetColor(0,1,0);
  input2Actor->SetPosition(
    -2.0 * (input2->GetBounds()[1]-input2->GetBounds()[0]),
    0, 0);
  vtkSmartPointer<vtkBooleanOperationPolyDataFilter> booleanOperation =
    vtkSmartPointer<vtkBooleanOperationPolyDataFilter>::New();
  if (operation == "union")
  {
      booleanOperation->SetOperationToUnion();
  }
  else if (operation == "intersection")
  {
      booleanOperation->SetOperationToIntersection();
  }
  else if (operation == "difference")
  {
      booleanOperation->SetOperationToDifference();
  }
  else
  {
    std::cout << "Unknown operation: " << operation << std::endl;
    return EXIT_FAILURE;
  }
#if VTK_MAJOR_VERSION <= 5
  booleanOperation->SetInputConnection( 0, input1->GetProducerPort() );
  booleanOperation->SetInputConnection( 1, input2->GetProducerPort() );
#else
  booleanOperation->SetInputData( 0, input1 );
  booleanOperation->SetInputData( 1, input2 );
#endif
  vtkSmartPointer<vtkPolyDataMapper> booleanOperationMapper =
    vtkSmartPointer<vtkPolyDataMapper>::New();
  booleanOperationMapper->SetInputConnection( booleanOperation->GetOutputPort() );
  booleanOperationMapper->ScalarVisibilityOff();

  vtkSmartPointer<vtkActor> booleanOperationActor =
    vtkSmartPointer<vtkActor>::New();
  booleanOperationActor->SetMapper( booleanOperationMapper );

  vtkSmartPointer<vtkRenderer> renderer =
    vtkSmartPointer<vtkRenderer>::New();
//  renderer->AddViewProp(input1Actor);
//  renderer->AddViewProp(input2Actor);
  renderer->AddViewProp(booleanOperationActor);
  renderer->SetBackground(.1, .2, .3);
  vtkSmartPointer<vtkRenderWindow> renderWindow =
    vtkSmartPointer<vtkRenderWindow>::New();
  renderWindow->AddRenderer( renderer );

  vtkSmartPointer<vtkRenderWindowInteractor> renWinInteractor =
    vtkSmartPointer<vtkRenderWindowInteractor>::New();
  renWinInteractor->SetRenderWindow( renderWindow );

  renderWindow->Render();
  renWinInteractor->Start();

  return EXIT_SUCCESS;
}
<commit_msg>BUG: Wrong position for actors<commit_after>#include <vtkVersion.h>
#include <vtkBooleanOperationPolyDataFilter.h>

#include <vtkActor.h>
#include <vtkSTLReader.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>

int main(int argc, char *argv[])
{
  vtkSmartPointer<vtkPolyData> input1;
  vtkSmartPointer<vtkPolyData> input2;

  std::string operation("intersection");

  if (argc == 4)
  {
    vtkSmartPointer<vtkSTLReader> reader1 =
      vtkSmartPointer<vtkSTLReader>::New();
    reader1->SetFileName(argv[1]);
    reader1->Update();
    input1 = reader1->GetOutput();

    vtkSmartPointer<vtkSTLReader> reader2 =
      vtkSmartPointer<vtkSTLReader>::New();
    reader2->SetFileName(argv[3]);
    reader2->Update();
    input2 = reader2->GetOutput();

    operation = argv[2];
  }
  else
  {
    vtkSmartPointer<vtkSphereSource> sphereSource1 =
      vtkSmartPointer<vtkSphereSource>::New();
    sphereSource1->SetCenter(.25, 0, 0);
    sphereSource1->Update();
    input1 = sphereSource1->GetOutput();

    vtkSmartPointer<vtkSphereSource> sphereSource2 =
      vtkSmartPointer<vtkSphereSource>::New();
    sphereSource2->Update();
    input2 = sphereSource2->GetOutput();

    if (argc == 2)
    {
      operation = argv[1];
    }
  }

  vtkSmartPointer<vtkPolyDataMapper> input1Mapper =
    vtkSmartPointer<vtkPolyDataMapper>::New();
#if VTK_MAJOR_VERSION <= 5
  input1Mapper->SetInputConnection( input1->GetProducerPort() );
#else
  input1Mapper->SetInputData( input1 );
#endif
  input1Mapper->ScalarVisibilityOff();
  vtkSmartPointer<vtkActor> input1Actor =
    vtkSmartPointer<vtkActor>::New();
  input1Actor->SetMapper( input1Mapper );
  input1Actor->GetProperty()->SetColor(1,0,0);
  input1Actor->SetPosition(
    input1->GetBounds()[1]-input1->GetBounds()[0],
    0, 0);
  vtkSmartPointer<vtkPolyDataMapper> input2Mapper =
    vtkSmartPointer<vtkPolyDataMapper>::New();
#if VTK_MAJOR_VERSION <= 5
  input2Mapper->SetInputConnection( input2->GetProducerPort() );
#else
  input2Mapper->SetInputData( input2 );
#endif
  input2Mapper->ScalarVisibilityOff();
  vtkSmartPointer<vtkActor> input2Actor =
    vtkSmartPointer<vtkActor>::New();
  input2Actor->SetMapper( input2Mapper );
  input2Actor->GetProperty()->SetColor(0,1,0);
  input2Actor->SetPosition(
    -(input2->GetBounds()[1]-input2->GetBounds()[0]),
    0, 0);
  vtkSmartPointer<vtkBooleanOperationPolyDataFilter> booleanOperation =
    vtkSmartPointer<vtkBooleanOperationPolyDataFilter>::New();
  if (operation == "union")
  {
      booleanOperation->SetOperationToUnion();
  }
  else if (operation == "intersection")
  {
      booleanOperation->SetOperationToIntersection();
  }
  else if (operation == "difference")
  {
      booleanOperation->SetOperationToDifference();
  }
  else
  {
    std::cout << "Unknown operation: " << operation << std::endl;
    return EXIT_FAILURE;
  }
#if VTK_MAJOR_VERSION <= 5
  booleanOperation->SetInputConnection( 0, input1->GetProducerPort() );
  booleanOperation->SetInputConnection( 1, input2->GetProducerPort() );
#else
  booleanOperation->SetInputData( 0, input1 );
  booleanOperation->SetInputData( 1, input2 );
#endif
  vtkSmartPointer<vtkPolyDataMapper> booleanOperationMapper =
    vtkSmartPointer<vtkPolyDataMapper>::New();
  booleanOperationMapper->SetInputConnection( booleanOperation->GetOutputPort() );
  booleanOperationMapper->ScalarVisibilityOff();

  vtkSmartPointer<vtkActor> booleanOperationActor =
    vtkSmartPointer<vtkActor>::New();
  booleanOperationActor->SetMapper( booleanOperationMapper );

  vtkSmartPointer<vtkRenderer> renderer =
    vtkSmartPointer<vtkRenderer>::New();
  renderer->AddViewProp(input1Actor);
  renderer->AddViewProp(input2Actor);
  renderer->AddViewProp(booleanOperationActor);
  renderer->SetBackground(.1, .2, .3);
  vtkSmartPointer<vtkRenderWindow> renderWindow =
    vtkSmartPointer<vtkRenderWindow>::New();
  renderWindow->AddRenderer( renderer );

  vtkSmartPointer<vtkRenderWindowInteractor> renWinInteractor =
    vtkSmartPointer<vtkRenderWindowInteractor>::New();
  renWinInteractor->SetRenderWindow( renderWindow );

  renderWindow->Render();
  renWinInteractor->Start();

  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/*
  This is a tool shipped by 'Aleph - A Library for Exploring Persistent
  Homology'.

  Its purpose is to create a *cover tree* for an input point cloud
  of arbitrary dimensionality. The cover tree creation process can
  be manipulated to some extent.
*/

#include <aleph/geometry/CoverTree.hh>
#include <aleph/geometry/Point.hh>

#include <aleph/geometry/distances/Euclidean.hh>
#include <aleph/geometry/distances/Wrapper.hh>

#include <aleph/utilities/String.hh>

#include <algorithm>
#include <fstream>
#include <istream>
#include <stdexcept>
#include <string>
#include <vector>

#include <getopt.h>

using DataType  = double;
using Point     = aleph::geometry::Point<DataType>;
using Distance  = aleph::geometry::distances::Euclidean<DataType>;
using Wrapper   = aleph::geometry::distances::Wrapper<Distance, Point>;
using CoverTree = aleph::geometry::CoverTree<Point, Wrapper>;

std::vector<Point> load( std::istream& in )
{
  using namespace aleph::utilities;

  std::vector<Point> points;
  std::string line;

  while( std::getline( in, line ) )
  {
    line        = trim( line );
    auto tokens = splitByWhitespace( line );

    // Skip empty lines and comment lines
    if( line.empty() || line.front() == '#' || tokens.empty() )
      continue;

    std::vector<DataType> values;

    std::transform( tokens.begin(), tokens.end(),
      std::back_inserter( values ),
      [] ( const std::string& token )
      {
        return static_cast<DataType>( std::stod( token ) );
      }
    );

    points.emplace_back( Point( values.begin(), values.end() ) );
  }

  return points;
}

std::vector<Point> load( const std::string& filename )
{
  std::ifstream in( filename );
  if( !in )
    throw std::runtime_error( "Unable to open input filename" );

  return load( in );
}

int main( int argc, char** argv )
{
  // Linkage criterion to use for constructing a hierarchical graph from
  // the cover tree. Currently, this is *not* used.
  std::string linkage = "single";

  {
    static option commandLineOptions[] =
    {
      { "linkage", required_argument, nullptr, 'l' },
      { nullptr  ,                 0, nullptr,  0  }
    };

    int option = 0;
    while( ( option = getopt_long( argc, argv, "l:", commandLineOptions, nullptr ) ) != -1 )
    {
      switch( option )
      {
      case 'l':
        linkage = optarg;
        break;
      default:
        throw std::runtime_error( "Unknown command-line option" );
      }
    }
  }
}
<commit_msg>Implemented (simple) point loading and sanity check<commit_after>/*
  This is a tool shipped by 'Aleph - A Library for Exploring Persistent
  Homology'.

  Its purpose is to create a *cover tree* for an input point cloud
  of arbitrary dimensionality. The cover tree creation process can
  be manipulated to some extent.
*/

#include <aleph/geometry/CoverTree.hh>
#include <aleph/geometry/Point.hh>

#include <aleph/geometry/distances/Euclidean.hh>
#include <aleph/geometry/distances/Wrapper.hh>

#include <aleph/utilities/String.hh>

#include <algorithm>
#include <fstream>
#include <iostream>
#include <istream>
#include <stdexcept>
#include <string>
#include <vector>

#include <getopt.h>

using DataType  = double;
using Point     = aleph::geometry::Point<DataType>;
using Distance  = aleph::geometry::distances::Euclidean<DataType>;
using Wrapper   = aleph::geometry::distances::Wrapper<Distance, Point>;
using CoverTree = aleph::geometry::CoverTree<Point, Wrapper>;

std::vector<Point> load( std::istream& in )
{
  using namespace aleph::utilities;

  std::vector<Point> points;
  std::string line;

  while( std::getline( in, line ) )
  {
    line        = trim( line );
    auto tokens = splitByWhitespace( line );

    // Skip empty lines and comment lines
    if( line.empty() || line.front() == '#' || tokens.empty() )
      continue;

    std::vector<DataType> values;

    std::transform( tokens.begin(), tokens.end(),
      std::back_inserter( values ),
      [] ( const std::string& token )
      {
        return static_cast<DataType>( std::stod( token ) );
      }
    );

    points.emplace_back( Point( values.begin(), values.end() ) );
  }

  if( !points.empty() )
  {
    auto d = points.front().dimension();
    for( auto&& p : points )
      if( p.dimension() != d )
        throw std::runtime_error( "Dimension of points must not vary" );
  }

  return points;
}

std::vector<Point> load( const std::string& filename )
{
  std::ifstream in( filename );
  if( !in )
    throw std::runtime_error( "Unable to open input filename" );

  return load( in );
}

int main( int argc, char** argv )
{
  // Linkage criterion to use for constructing a hierarchical graph from
  // the cover tree. Currently, this is *not* used.
  std::string linkage = "single";

  {
    static option commandLineOptions[] =
    {
      { "linkage", required_argument, nullptr, 'l' },
      { nullptr  ,                 0, nullptr,  0  }
    };

    int option = 0;
    while( ( option = getopt_long( argc, argv, "l:", commandLineOptions, nullptr ) ) != -1 )
    {
      switch( option )
      {
      case 'l':
        linkage = optarg;
        break;
      default:
        throw std::runtime_error( "Unknown command-line option" );
      }
    }
  }

  // The remaining command-line arguments are considered to be file
  // names. The name '-' deserves special handling.
  std::string filename = argv[ optind++ ];

  std::vector<Point> points;
  if( filename == "-" )
    points = load( std::cin );
  else
    points = load( filename );

  // Nothing to do here
  if( points.empty() )
    return 0;

  std::cerr << "* Read "
            << filename.size()
            << " points of dimension "
            << points.front().dimension()
            << "\n";
}
<|endoftext|>


<commit_before>#include "kumirinterface.h"
#include "ui_mainwindow.h"
#include "plugininterface.h"
#include <QtGui>
#include <QtCore>
kumirInterface::kumirInterface(const QString& path, QMainWindow* ui)
{
    //****
    int moduleId = 0;
    //****

    qDebug()<<"asd";
    //QString path = QCoreApplication::applicationDirPath()+"/../TextEditor/";
    //path = QDir::cleanPath(path);
    //path = QDir::toNativeSeparators(path);
    QDir dir(path);
    QStringList filters;
    QStringList libNames;
    filters << "*.so";
    dir.setNameFilters(filters);
    libNames = dir.entryList();

    QToolBar* kumirToolBar = new QToolBar();
    Q_FOREACH(QString name, libNames)
    {
        qDebug()<<name;

        QPluginLoader L(dir.absoluteFilePath(name));
        L.load();
        qDebug()<<L.errorString();
        QObject* obj = L.instance();
        qDebug()<<obj;
        if(!obj)
        {
            continue;
        }
        else
        {
            Shared::ActorInterface * p = qobject_cast<Shared::ActorInterface*>(obj);
            Shared::PluginInterface * p1 = qobject_cast<Shared::PluginInterface*>(obj);
            qDebug()<<"asd";
            if(!p||!p1)
            {
                continue;
            }
            else
            {
                QString fileName = QDesktopServices::storageLocation(QDesktopServices::TempLocation)+'/' + p->asciiModuleName().replace(" ","_")+".py";

                qDebug()<<fileName;
                QFile codeGenerateFile(fileName);
                codeGenerateFile.open(QIODevice::WriteOnly);
                codeGenerateFile.write("import _myModule\n");

                p1->initialize(path+"/"+p->asciiModuleName().toLower());
                qDebug()<<name<<"\n";
                qDebug()<<p->asciiModuleName()<<"\n";
                instanced.push_back(p);
                ui->menuBar()->addSeparator();

                QList<class QMenu*> b = p->moduleMenus();
                Q_FOREACH(QMenu* a, b)
                {
                    ui->menuBar()->addMenu(a);
                    //p->mainWidget()->show();
                    QAction* act = kumirToolBar->addAction(p->asciiModuleName()+" show");
                    QObject::connect(act, SIGNAL(triggered()),
                                     p->mainWidget(), SLOT(show()));

                }

                QStringList codeGenerator;
                for(int i = 0; i < p->functionList().size(); i++)
                {
                    Shared::ActorInterface::Function func = p->functionList().at(i);
                    QString funcName ="def ";
                    funcName.append(func.asciiName);
                    funcName.replace(" ", "_");
                    funcName[3] = ' ';
                    funcName.append('(');
                    for(int k = 0; k < func.arguments.size(); k++)
                    {

                        funcName.append("arg");
                        funcName.append(QString::number(k));
                        if(k<func.arguments.size()-1)
                            funcName.append(',');
                    }
                    funcName.append("):\n    ");
                    funcName.append("_myModule.actor_call("); //0, 1, [arg1, arg1, arg3])

                    funcName.append(QString::number(moduleId));
                    funcName.append(", ");

                    funcName.append(QString::number(func.id));
                    funcName.append(", [");
                    for(int k = 0; k < func.arguments.size(); k++)
                    {

                        funcName.append("arg");
                        funcName.append(QString::number(k));
                        if(k<func.arguments.size()-1)
                            funcName.append(',');
                    }
                    funcName.append("])\n");
                    qDebug()<<funcName;
                    QTextStream ts(&codeGenerateFile);
                    ts.operator <<(funcName);

                    codeGenerator.append(funcName);
                }
                codeGenerateFile.close();

                moduleId++;
            }
        }
    }
    ui->addToolBar(kumirToolBar);
}
kumirInterface* kumirInterface::get(const QString &path, QMainWindow *ui)
{
    static kumirInterface* a = NULL;
    if(a == NULL)
    {
        a = new kumirInterface(path, ui);
    }
    return a;
}
<commit_msg>Disabled @-special functions<commit_after>#include "kumirinterface.h"
#include "ui_mainwindow.h"
#include "plugininterface.h"
#include <QtGui>
#include <QtCore>
kumirInterface::kumirInterface(const QString& path, QMainWindow* ui)
{
    //****
    int moduleId = 0;
    //****

    qDebug()<<"asd";
    //QString path = QCoreApplication::applicationDirPath()+"/../TextEditor/";
    //path = QDir::cleanPath(path);
    //path = QDir::toNativeSeparators(path);
    QDir dir(path);
    QStringList filters;
    QStringList libNames;
    filters << "*.so";
    dir.setNameFilters(filters);
    libNames = dir.entryList();

    QToolBar* kumirToolBar = new QToolBar();
    Q_FOREACH(QString name, libNames)
    {
        qDebug()<<name;

        QPluginLoader L(dir.absoluteFilePath(name));
        L.load();
        qDebug()<<L.errorString();
        QObject* obj = L.instance();
        qDebug()<<obj;
        if(!obj)
        {
            continue;
        }
        else
        {
            Shared::ActorInterface * p = qobject_cast<Shared::ActorInterface*>(obj);
            Shared::PluginInterface * p1 = qobject_cast<Shared::PluginInterface*>(obj);
            qDebug()<<"asd";
            if(!p||!p1)
            {
                continue;
            }
            else
            {
                QString fileName = QDesktopServices::storageLocation(QDesktopServices::TempLocation)+'/' + p->asciiModuleName().replace(" ","_")+".py";

                qDebug()<<fileName;
                QFile codeGenerateFile(fileName);
                codeGenerateFile.open(QIODevice::WriteOnly);
                codeGenerateFile.write("import _myModule\n");

                p1->initialize(path+"/"+p->asciiModuleName().toLower().replace(' ', ""));
                qDebug()<<name<<"\n";
                qDebug()<<p->asciiModuleName()<<"\n";
                instanced.push_back(p);
                ui->menuBar()->addSeparator();

                QList<class QMenu*> b = p->moduleMenus();
                Q_FOREACH(QMenu* a, b)
                {
                    ui->menuBar()->addMenu(a);
                    //p->mainWidget()->show();
                    QAction* act = kumirToolBar->addAction(p->asciiModuleName()+" show");
                    QObject::connect(act, SIGNAL(triggered()),
                                     p->mainWidget(), SLOT(show()));

                }

                QStringList codeGenerator;
                for(int i = 0; i < p->functionList().size(); i++)
                {
                    Shared::ActorInterface::Function func = p->functionList().at(i);
                    if (func.asciiName.startsWith("@"))
                        continue;
                    QString funcName ="def ";
                    funcName.append(func.asciiName);
                    funcName.replace(" ", "_");
                    funcName[3] = ' ';
                    funcName.append('(');
                    for(int k = 0; k < func.arguments.size(); k++)
                    {

                        funcName.append("arg");
                        funcName.append(QString::number(k));
                        if(k<func.arguments.size()-1)
                            funcName.append(',');
                    }
                    funcName.append("):\n    ");
                    funcName.append("_myModule.actor_call("); //0, 1, [arg1, arg1, arg3])

                    funcName.append(QString::number(moduleId));
                    funcName.append(", ");

                    funcName.append(QString::number(func.id));
                    funcName.append(", [");
                    for(int k = 0; k < func.arguments.size(); k++)
                    {

                        funcName.append("arg");
                        funcName.append(QString::number(k));
                        if(k<func.arguments.size()-1)
                            funcName.append(',');
                    }
                    funcName.append("])\n");
                    qDebug()<<funcName;
                    QTextStream ts(&codeGenerateFile);
                    ts.operator <<(funcName);

                    codeGenerator.append(funcName);
                }
                codeGenerateFile.close();

                moduleId++;
            }
        }
    }
    ui->addToolBar(kumirToolBar);
}
kumirInterface* kumirInterface::get(const QString &path, QMainWindow *ui)
{
    static kumirInterface* a = NULL;
    if(a == NULL)
    {
        a = new kumirInterface(path, ui);
    }
    return a;
}
<|endoftext|>