<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/*
 * $Log$
 * Revision 1.5  2000/02/24 20:12:55  abagchi
 * Swat for removing Log from API docs
 *
 * Revision 1.4  2000/02/12 03:31:55  rahulj
 * Removed duplicate CVS Log entries.
 *
 * Revision 1.3  2000/02/12 01:27:19  aruna1
 * Documentation updated
 *
 * Revision 1.2  2000/02/06 07:47:57  rahulj
 * Year 2K copyright swat.
 *
 * Revision 1.1.1.1  1999/11/09 01:07:45  twl
 * Initial checkin
 *
 * Revision 1.2  1999/11/08 20:45:00  rahul
 * Swat for adding in Product name and CVS comment log variable.
 *
 */

#ifndef ERRORHANDLER_HPP
#define ERRORHANDLER_HPP

class SAXParseException;

/**
  * Basic interface for SAX error handlers.
  *
  *
If a SAX application needs to implement customized error
  * handling, it must implement this interface and then register an
  * instance with the SAX parser using the parser's setErrorHandler
  * method.  The parser will then report all errors and warnings
  * through this interface.

  *
  *
 The parser shall use this interface instead of throwing an
  * exception: it is up to the application whether to throw an
  * exception for different types of errors and warnings.  Note,
  * however, that there is no requirement that the parser continue to
  * provide useful information after a call to fatalError (in other
  * words, a SAX driver class could catch an exception and report a
  * fatalError).

  *
  *
The HandlerBase class provides a default implementation of this
  * interface, ignoring warnings and recoverable errors and throwing a
  * SAXParseException for fatal errors.  An application may extend
  * that class rather than implementing the complete interface
  * itself.

  *
  * @see Parser#setErrorHandler
  * @see SAXParseException#SAXParseException
  * @see HandlerBase#HandlerBase
  */

class SAX_EXPORT ErrorHandler
{
public:
    /** @name Constructors and Destructor */
    //@{
    /** Default constructor */
    ErrorHandler()
    {
    }

    /** Desctructor */
    virtual ~ErrorHandler()
    {
    }
    //@}

    /** @name The error handler interface */
    //@{
   /**
    * Receive notification of a warning.
    *
    *
SAX parsers will use this method to report conditions that
    * are not errors or fatal errors as defined by the XML 1.0
    * recommendation.  The default behaviour is to take no action.

    *
    *
The SAX parser must continue to provide normal parsing events
    * after invoking this method: it should still be possible for the
    * application to process the document through to the end.

    *
    * @param exception The warning information encapsulated in a
    *                  SAX parse exception.
    * @exception SAXException Any SAX exception, possibly
    *            wrapping another exception.
    * @see SAXParseException#SAXParseException
    */
    virtual void warning(const SAXParseException& exception) = 0;

  /**
    * Receive notification of a recoverable error.
    *
    *
This corresponds to the definition of "error" in section 1.2
    * of the W3C XML 1.0 Recommendation.  For example, a validating
    * parser would use this callback to report the violation of a
    * validity constraint.  The default behaviour is to take no
    * action.

    *
    *
The SAX parser must continue to provide normal parsing events
    * after invoking this method: it should still be possible for the
    * application to process the document through to the end.  If the
    * application cannot do so, then the parser should report a fatal
    * error even if the XML 1.0 recommendation does not require it to
    * do so.

    *
    * @param exception The error information encapsulated in a
    *                  SAX parse exception.
    * @exception SAXException Any SAX exception, possibly
    *            wrapping another exception.
    * @see SAXParseException#SAXParseException
    */
    virtual void error(const SAXParseException& exception) = 0;

  /**
    * Receive notification of a non-recoverable error.
    *
    *
This corresponds to the definition of "fatal error" in
    * section 1.2 of the W3C XML 1.0 Recommendation.  For example, a
    * parser would use this callback to report the violation of a
    * well-formedness constraint.

    *
    *
The application must assume that the document is unusable
    * after the parser has invoked this method, and should continue
    * (if at all) only for the sake of collecting addition error
    * messages: in fact, SAX parsers are free to stop reporting any
    * other events once this method has been invoked.

    *
    * @param exception The error information encapsulated in a
    *                  SAX parse exception.
    * @exception SAXException Any SAX exception, possibly
    *            wrapping another exception.
    * @see SAXParseException#SAXParseException
    */
    virtual void fatalError(const SAXParseException& exception) = 0;

    /**
    * Reset the Error handler object on its reuse
    *
    *
This method helps in reseting the Error handler object
    * implementational defaults each time the Error handler is begun.

    *
    */
    virtual void resetErrors() = 0;

    //@}

private :
    /* Unimplemented constructors and operators */

    /* Copy constructor */
    ErrorHandler(const ErrorHandler&);

    /* Assignment operator */
    void operator=(const ErrorHandler&);

};

#endif
<commit_msg>Included <util/XercesDefs.hpp> as suggested by David N Bertoni.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/*
 * $Log$
 * Revision 1.6  2000/04/27 19:33:15  rahulj
 * Included <util/XercesDefs.hpp> as suggested by David N Bertoni.
 *
 * Revision 1.5  2000/02/24 20:12:55  abagchi
 * Swat for removing Log from API docs
 *
 * Revision 1.4  2000/02/12 03:31:55  rahulj
 * Removed duplicate CVS Log entries.
 *
 * Revision 1.3  2000/02/12 01:27:19  aruna1
 * Documentation updated
 *
 * Revision 1.2  2000/02/06 07:47:57  rahulj
 * Year 2K copyright swat.
 *
 * Revision 1.1.1.1  1999/11/09 01:07:45  twl
 * Initial checkin
 *
 * Revision 1.2  1999/11/08 20:45:00  rahul
 * Swat for adding in Product name and CVS comment log variable.
 *
 */

#ifndef ERRORHANDLER_HPP
#define ERRORHANDLER_HPP

#include <util/XercesDefs.hpp>

class SAXParseException;

/**
  * Basic interface for SAX error handlers.
  *
  *
If a SAX application needs to implement customized error
  * handling, it must implement this interface and then register an
  * instance with the SAX parser using the parser's setErrorHandler
  * method.  The parser will then report all errors and warnings
  * through this interface.

  *
  *
 The parser shall use this interface instead of throwing an
  * exception: it is up to the application whether to throw an
  * exception for different types of errors and warnings.  Note,
  * however, that there is no requirement that the parser continue to
  * provide useful information after a call to fatalError (in other
  * words, a SAX driver class could catch an exception and report a
  * fatalError).

  *
  *
The HandlerBase class provides a default implementation of this
  * interface, ignoring warnings and recoverable errors and throwing a
  * SAXParseException for fatal errors.  An application may extend
  * that class rather than implementing the complete interface
  * itself.

  *
  * @see Parser#setErrorHandler
  * @see SAXParseException#SAXParseException
  * @see HandlerBase#HandlerBase
  */

class SAX_EXPORT ErrorHandler
{
public:
    /** @name Constructors and Destructor */
    //@{
    /** Default constructor */
    ErrorHandler()
    {
    }

    /** Desctructor */
    virtual ~ErrorHandler()
    {
    }
    //@}

    /** @name The error handler interface */
    //@{
   /**
    * Receive notification of a warning.
    *
    *
SAX parsers will use this method to report conditions that
    * are not errors or fatal errors as defined by the XML 1.0
    * recommendation.  The default behaviour is to take no action.

    *
    *
The SAX parser must continue to provide normal parsing events
    * after invoking this method: it should still be possible for the
    * application to process the document through to the end.

    *
    * @param exception The warning information encapsulated in a
    *                  SAX parse exception.
    * @exception SAXException Any SAX exception, possibly
    *            wrapping another exception.
    * @see SAXParseException#SAXParseException
    */
    virtual void warning(const SAXParseException& exception) = 0;

  /**
    * Receive notification of a recoverable error.
    *
    *
This corresponds to the definition of "error" in section 1.2
    * of the W3C XML 1.0 Recommendation.  For example, a validating
    * parser would use this callback to report the violation of a
    * validity constraint.  The default behaviour is to take no
    * action.

    *
    *
The SAX parser must continue to provide normal parsing events
    * after invoking this method: it should still be possible for the
    * application to process the document through to the end.  If the
    * application cannot do so, then the parser should report a fatal
    * error even if the XML 1.0 recommendation does not require it to
    * do so.

    *
    * @param exception The error information encapsulated in a
    *                  SAX parse exception.
    * @exception SAXException Any SAX exception, possibly
    *            wrapping another exception.
    * @see SAXParseException#SAXParseException
    */
    virtual void error(const SAXParseException& exception) = 0;

  /**
    * Receive notification of a non-recoverable error.
    *
    *
This corresponds to the definition of "fatal error" in
    * section 1.2 of the W3C XML 1.0 Recommendation.  For example, a
    * parser would use this callback to report the violation of a
    * well-formedness constraint.

    *
    *
The application must assume that the document is unusable
    * after the parser has invoked this method, and should continue
    * (if at all) only for the sake of collecting addition error
    * messages: in fact, SAX parsers are free to stop reporting any
    * other events once this method has been invoked.

    *
    * @param exception The error information encapsulated in a
    *                  SAX parse exception.
    * @exception SAXException Any SAX exception, possibly
    *            wrapping another exception.
    * @see SAXParseException#SAXParseException
    */
    virtual void fatalError(const SAXParseException& exception) = 0;

    /**
    * Reset the Error handler object on its reuse
    *
    *
This method helps in reseting the Error handler object
    * implementational defaults each time the Error handler is begun.

    *
    */
    virtual void resetErrors() = 0;

    //@}

private :
    /* Unimplemented constructors and operators */

    /* Copy constructor */
    ErrorHandler(const ErrorHandler&);

    /* Assignment operator */
    void operator=(const ErrorHandler&);

};

#endif
<|endoftext|>


<commit_before>// Copyright 2014 Alessio Sclocco <a.sclocco@vu.nl>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <iostream>
#include <fstream>
#include <exception>
#include <string>
#include <utility>
#include <map>
#include <iomanip>

#include <ArgumentList.hpp>
#include <utils.hpp>

int main(int argc, char * argv[]) {
  // DMs
  float firstDM = 0.0f;
  float stepDM = 0.0f;
  // Periods
  unsigned int firstPeriod = 0;
  unsigned int stepPeriod = 0;
  // Sampling
  unsigned int nrSamplesPerSecond = 0;
  // I/O
  std::string outFilename;
  std::ifstream searchFile;
  std::ofstream outFile;
  // Data
  unsigned int percentile = 0;
  std::multimap< float, std::pair< unsigned int, unsigned int > > snrList;

  isa::utils::ArgumentList args(argc, argv);
  try {
    outFilename = args.getSwitchArgument< std::string >("-output");
    firstDM = args.getSwitchArgument< float >("-dm_first");
    stepDM = args.getSwitchArgument< float >("-dm_step");
    firstPeriod = args.getSwitchArgument< unsigned int >("-period_first");
    stepPeriod = args.getSwitchArgument< unsigned int >("-period_step");
    nrSamplesPerSecond = args.getSwitchArgument< unsigned int >("-samples");
    percentile = args.getSwitchArgument< unsigned int >("-percentile");
  } catch ( isa::utils::EmptyCommandLine & err ) {
    std::cerr << args.getName() << " -output ... -dm_first ... -dm_step ... -period_first ... -period_step ... -samples ... -percentile ... input" << std::endl;
    return 1;
  } catch ( std::exception & err ) {
    std::cerr << err.what() << std::endl;
    return 1;
  }

  // Read the SNR data
  try {
    while ( true ) {
      searchFile.open(args.getFirst< std::string >());

      while ( ! searchFile.eof() ) {
        std::string temp;
        unsigned int splitPoint = 0;
        unsigned int DM = 0;
        unsigned int period = 0;
        float snr = 0.0f;

        std::getline(searchFile, temp);
        if ( ! std::isdigit(temp[0]) ) {
          continue;
        }
        splitPoint = temp.find(" ");
        period = isa::utils::castToType< std::string, unsigned int >(temp.substr(0, splitPoint));
        temp = temp.substr(splitPoint + 1);
        splitPoint = temp.find(" ");
        DM = isa::utils::castToType< std::string, unsigned int >(temp.substr(0, splitPoint));
        temp = temp.substr(splitPoint + 1);
        splitPoint = temp.find(" ");
        snr = isa::utils::castToType< std::string, float >(temp);

        snrList.insert(std::make_pair(snr, std::make_pair(DM, period)));
      }
      searchFile.close();
    }
  } catch ( isa::utils::EmptyCommandLine & err ) {
  }

  // Print the percentile
  unsigned int lowerLimit = (percentile * snrList.size()) / 100;
  unsigned int counter = snrList.size() - 1;
  outFile.open(outFilename);
  outFile << std::fixed;
  outFile << "# DMIndex DM periodIndex period snr" << std::endl;
  for ( std::multimap< float, std::pair< unsigned int, unsigned int> >::const_reverse_iterator item = snrList.crend(); counter >= lowerLimit; counter-- ) {
  ++item;
  outFile << std::setprecision(2);
  outFile << (*item).second.first << " " << firstDM + ((*item).second.first * stepDM) << " ";
  outFile << std::setprecision(6);
  outFile << (*item).second.second << " " << (firstPeriod + ((*item).second.second * stepPeriod)) / static_cast< float >(nrSamplesPerSecond) << " ";
  outFile << (*item).first << std::endl;
  }
  outFile.close();

  return 0;
}

<commit_msg>The percentile is a floating point number.<commit_after>// Copyright 2014 Alessio Sclocco <a.sclocco@vu.nl>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <iostream>
#include <fstream>
#include <exception>
#include <string>
#include <utility>
#include <map>
#include <iomanip>

#include <ArgumentList.hpp>
#include <utils.hpp>

int main(int argc, char * argv[]) {
  // DMs
  float firstDM = 0.0f;
  float stepDM = 0.0f;
  // Periods
  unsigned int firstPeriod = 0;
  unsigned int stepPeriod = 0;
  // Sampling
  unsigned int nrSamplesPerSecond = 0;
  // I/O
  std::string outFilename;
  std::ifstream searchFile;
  std::ofstream outFile;
  // Data
  float percentile = 0;
  std::multimap< float, std::pair< unsigned int, unsigned int > > snrList;

  isa::utils::ArgumentList args(argc, argv);
  try {
    outFilename = args.getSwitchArgument< std::string >("-output");
    firstDM = args.getSwitchArgument< float >("-dm_first");
    stepDM = args.getSwitchArgument< float >("-dm_step");
    firstPeriod = args.getSwitchArgument< unsigned int >("-period_first");
    stepPeriod = args.getSwitchArgument< unsigned int >("-period_step");
    nrSamplesPerSecond = args.getSwitchArgument< unsigned int >("-samples");
    percentile = args.getSwitchArgument< float >("-percentile");
  } catch ( isa::utils::EmptyCommandLine & err ) {
    std::cerr << args.getName() << " -output ... -dm_first ... -dm_step ... -period_first ... -period_step ... -samples ... -percentile ... input" << std::endl;
    return 1;
  } catch ( std::exception & err ) {
    std::cerr << err.what() << std::endl;
    return 1;
  }

  // Read the SNR data
  try {
    while ( true ) {
      searchFile.open(args.getFirst< std::string >());

      while ( ! searchFile.eof() ) {
        std::string temp;
        unsigned int splitPoint = 0;
        unsigned int DM = 0;
        unsigned int period = 0;
        float snr = 0.0f;

        std::getline(searchFile, temp);
        if ( ! std::isdigit(temp[0]) ) {
          continue;
        }
        splitPoint = temp.find(" ");
        period = isa::utils::castToType< std::string, unsigned int >(temp.substr(0, splitPoint));
        temp = temp.substr(splitPoint + 1);
        splitPoint = temp.find(" ");
        DM = isa::utils::castToType< std::string, unsigned int >(temp.substr(0, splitPoint));
        temp = temp.substr(splitPoint + 1);
        splitPoint = temp.find(" ");
        snr = isa::utils::castToType< std::string, float >(temp);

        snrList.insert(std::make_pair(snr, std::make_pair(DM, period)));
      }
      searchFile.close();
    }
  } catch ( isa::utils::EmptyCommandLine & err ) {
  }

  // Print the percentile
  unsigned int lowerLimit = static_cast< unsigned int >((percentile * snrList.size()) / 100.0);
  unsigned int counter = snrList.size() - 1;
  outFile.open(outFilename);
  outFile << std::fixed;
  outFile << "# DMIndex DM periodIndex period snr" << std::endl;
  for ( std::multimap< float, std::pair< unsigned int, unsigned int> >::const_reverse_iterator item = snrList.crend(); counter >= lowerLimit; counter-- ) {
  ++item;
  outFile << std::setprecision(2);
  outFile << (*item).second.first << " " << firstDM + ((*item).second.first * stepDM) << " ";
  outFile << std::setprecision(6);
  outFile << (*item).second.second << " " << (firstPeriod + ((*item).second.second * stepPeriod)) / static_cast< float >(nrSamplesPerSecond) << " ";
  outFile << (*item).first << std::endl;
  }
  outFile.close();

  return 0;
}

<|endoftext|>


<commit_before>/*********************************************************************
 *
 * Authors: Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it
 *
 * Copyright (c) Members of the EGEE Collaboration. 2004-2010.
 * See http://www.eu-egee.org/partners/ for details on the copyright holders.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Parts of this code may be based upon or even include verbatim pieces,
 * originally written by other people, in which case the original header
 * follows.
 *
 *********************************************************************/
#include "config.h"

extern "C" {
#include "replace.h"
#include <stdio.h>
#include <ctype.h>
#include <openssl/evp.h>
#include <openssl/ssl.h>
#include <openssl/x509.h>

#include "sslutils.h"
#include "log.h"
#include "credentials.h"
}

#include <string>
#include <iostream>
#include "soapH.h"
#include "VOMSServer.h"
#include "fqan.h"
#include "data.h"

static int (*pw_cb)() = NULL;
static char *canonicalize_string(char *original);
static bool makeACSSL(vomsresult &vr, SSL *ssl, const std::string& command, const std::string &orderstring, const std::string& targets, int requested, VOMSServer *v);
static int makeACREST(struct soap *soap, const std::string& command, const std::string& orderstring, const std::string& targets, int requested, int unknown);
int http_get(soap *soap);
static int pwstdin_callback(char * buf, int num, UNUSED(int w));
static bool get_parameter(char **path, char **name, char **value);

extern VOMSServer *selfpointer;
extern void *logh;
extern char *maingroup;

static int pwstdin_callback(char * buf, int num, UNUSED(int w))
{
  int i;

  if (!(fgets(buf, num, stdin))) {
    std::cerr << "Failed to read pass-phrase from stdin" << std::endl;
    return -1;
  }
  i = strlen(buf);
  if (buf[i-1] == '\n') {
      buf[i-1] = '\0';
      i--;
  }
  return i;

}

static bool
makeACSSL(vomsresult &vr, SSL *ssl, const std::string& command, const std::string &orderstring, const std::string& targets, int requested, VOMSServer *v)
{
  X509 *holder = SSL_get_peer_certificate(ssl);
  STACK_OF(X509) *chain = SSL_get_peer_cert_chain(ssl);

  X509 *realholder = get_real_cert(holder, chain);
  X509 *issuer = NULL;
  EVP_PKEY *key = NULL;
  pw_cb =(int (*)())(pwstdin_callback);
  char *hostcert = (char*)"/etc/grid-security/hostcert.pem";
  char *hostkey  = (char*)"/etc/grid-security/hostkey.pem";

  if (!v->x509_user_cert.empty())
    hostcert = (char*)v->x509_user_cert.c_str();

  if (!v->x509_user_key.empty())
    hostkey = (char *)v->x509_user_key.c_str();

  if (!load_credentials(hostcert, hostkey,
                        &issuer, NULL,  &key, pw_cb)) {
    X509_free(issuer);
    EVP_PKEY_free(key);
    return false;
  }

  std::string message = XML_Req_Encode(command, orderstring, targets, requested);

  bool ret = selfpointer->makeAC(vr, key, issuer, realholder, message);
  X509_free(issuer);
  EVP_PKEY_free(key);

  return ret;
}

static int
makeACREST(struct soap *soap, const std::string& command, const std::string& orderstring, const std::string& targets, int requested, int unknown)
{
  vomsresult vr;

  if (unknown)
    vr.setError(WARN_UNKNOWN_COMMAND, "Unknown parameters in the request were ignored!");

  (void)makeACSSL(vr, (SSL*)soap->ssl, command, orderstring, targets, requested, selfpointer);

  int value;
  std::string output = vr.makeRESTAnswer(value);

  soap->http_content = "text/xml";
  soap_response(soap, value);
  soap_send(soap, output.c_str());
  soap_end_send(soap);

  return SOAP_OK;
}

int http_get(soap *soap)
{
  char *path = strdup(soap->path);
  int unknown = 0;

  LOGM(VARP, logh, LEV_DEBUG, T_PRE, "HTTP request: %s", soap->path);

  if (!path)
    return SOAP_GET_METHOD;

  char *s = strchr(path, '?');

  if (s)
    *s='\0';

  char *prepath=canonicalize_string(path);

  if (strcmp(prepath, "/generate-ac") != 0) {
    free(path);
    soap_response(soap, 404);
    soap_end_send(soap);
    return 404;
  }

  soap_response(soap, SOAP_HTML);

  /* determine parameters */
  std::vector<std::string> fqans;
  int lifetime = -1;
  std::string orderstring;
  std::string targetstring;

  if (s) {
    ++s;

    if (!strlen(s)) {
      free(path);
      soap_response(soap, 404);
      soap_end_send(soap);
      return 500;
    }

    char *basis = s;

    do {
      char *cname;
      char *cvalue;

      if (!get_parameter(&basis, &cname, &cvalue)) {
        free(path);
        soap_response(soap, 404);
        soap_end_send(soap);
        return 500;
      }

      if (strcmp(cname, "lifetime") == 0)
        lifetime = atoi(cvalue);

      else if (strcmp(cname, "fqans") == 0) {
        char *position = strchr(cvalue, ',');

        while (position) {
          *position = '\0';
          fqans.push_back(std::string(cvalue));
          cvalue = ++position;
          position = strchr(cvalue, ',');
        }
        fqans.push_back(std::string(cvalue));
      }

      else if (strcmp(cname, "order") == 0) {
        if (orderstring.empty())
          orderstring = std::string(cvalue);
        else
          orderstring += ", " + std::string(cvalue);
      }
      else if (strcmp(cname, "targets") == 0) {
        targetstring = std::string(cvalue);
      }
      else {
        /* purposefully ignore other parameters */
        /* but put it in an otherwise positive response */
        unknown = 1;
      }
    } while (basis);
  }

  if (fqans.size()==0)
    fqans.push_back(maingroup);

  std::string command = parse_fqan(fqans);

  int res = makeACREST(soap, command, orderstring, targetstring, lifetime, unknown);

  free(path);

  return res;
}

static bool get_parameter(char **path, char **name, char **value)
{
  if (!path || !name || !value)
    return false;

  char* next = strchr(*path, '&');

  if (next)
    *next='\0';

  char *equal = strchr(*path, '=');

  if (!equal)
    return false;

  *equal='\0';

  *name = *path;
  *value = equal+1;

  if (next)
    *path = ++next;
  else
    *path = next;

  return true;
}

static char *canonicalize_string(char *original)
{
  char *currentin  = original;
  char *currentout = original;

  while (*currentin != '\0') {
    if (*currentin != '%')
      *currentout++ = *currentin++;
    else {
      char first = *(currentin+1);

      if (first != '\0') {
        char second = *(currentin+2);

        if (second != '\0') {
          if (isxdigit(first) && isxdigit(second)) {
            *currentout++ = (hex2num(first) << 4) | hex2num(second);
            currentin += 3;
          }
          else
            *currentout++ = *currentin++;
        }
        else
          *currentout++ = *currentin++;
      }
      else
        *currentout++ = *currentin++;
    }
  }
  *currentout='\0';

  return original;
}

<commit_msg>don't use canonicalize_string<commit_after>/*********************************************************************
 *
 * Authors: Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it
 *
 * Copyright (c) Members of the EGEE Collaboration. 2004-2010.
 * See http://www.eu-egee.org/partners/ for details on the copyright holders.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Parts of this code may be based upon or even include verbatim pieces,
 * originally written by other people, in which case the original header
 * follows.
 *
 *********************************************************************/
#include "config.h"

extern "C" {
#include "replace.h"
#include <stdio.h>
#include <ctype.h>
#include <openssl/evp.h>
#include <openssl/ssl.h>
#include <openssl/x509.h>

#include "sslutils.h"
#include "log.h"
#include "credentials.h"
}

#include <string>
#include <iostream>
#include "soapH.h"
#include "VOMSServer.h"
#include "fqan.h"
#include "data.h"

static int (*pw_cb)() = NULL;
static bool makeACSSL(vomsresult &vr, SSL *ssl, const std::string& command, const std::string &orderstring, const std::string& targets, int requested, VOMSServer *v);
static int makeACREST(struct soap *soap, const std::string& command, const std::string& orderstring, const std::string& targets, int requested, int unknown);
int http_get(soap *soap);
static int pwstdin_callback(char * buf, int num, UNUSED(int w));
static bool get_parameter(char **path, char **name, char **value);

extern VOMSServer *selfpointer;
extern void *logh;
extern char *maingroup;

static int pwstdin_callback(char * buf, int num, UNUSED(int w))
{
  int i;

  if (!(fgets(buf, num, stdin))) {
    std::cerr << "Failed to read pass-phrase from stdin" << std::endl;
    return -1;
  }
  i = strlen(buf);
  if (buf[i-1] == '\n') {
      buf[i-1] = '\0';
      i--;
  }
  return i;

}

static bool
makeACSSL(vomsresult &vr, SSL *ssl, const std::string& command, const std::string &orderstring, const std::string& targets, int requested, VOMSServer *v)
{
  X509 *holder = SSL_get_peer_certificate(ssl);
  STACK_OF(X509) *chain = SSL_get_peer_cert_chain(ssl);

  X509 *realholder = get_real_cert(holder, chain);
  X509 *issuer = NULL;
  EVP_PKEY *key = NULL;
  pw_cb =(int (*)())(pwstdin_callback);
  char *hostcert = (char*)"/etc/grid-security/hostcert.pem";
  char *hostkey  = (char*)"/etc/grid-security/hostkey.pem";

  if (!v->x509_user_cert.empty())
    hostcert = (char*)v->x509_user_cert.c_str();

  if (!v->x509_user_key.empty())
    hostkey = (char *)v->x509_user_key.c_str();

  if (!load_credentials(hostcert, hostkey,
                        &issuer, NULL,  &key, pw_cb)) {
    X509_free(issuer);
    EVP_PKEY_free(key);
    return false;
  }

  std::string message = XML_Req_Encode(command, orderstring, targets, requested);

  bool ret = selfpointer->makeAC(vr, key, issuer, realholder, message);
  X509_free(issuer);
  EVP_PKEY_free(key);

  return ret;
}

static int
makeACREST(struct soap *soap, const std::string& command, const std::string& orderstring, const std::string& targets, int requested, int unknown)
{
  vomsresult vr;

  if (unknown)
    vr.setError(WARN_UNKNOWN_COMMAND, "Unknown parameters in the request were ignored!");

  (void)makeACSSL(vr, (SSL*)soap->ssl, command, orderstring, targets, requested, selfpointer);

  int value;
  std::string output = vr.makeRESTAnswer(value);

  soap->http_content = "text/xml";
  soap_response(soap, value);
  soap_send(soap, output.c_str());
  soap_end_send(soap);

  return SOAP_OK;
}

int http_get(soap *soap)
{
  char *path = strdup(soap->path);
  int unknown = 0;

  LOGM(VARP, logh, LEV_DEBUG, T_PRE, "HTTP request: %s", soap->path);

  if (!path)
    return SOAP_GET_METHOD;

  char *s = strchr(path, '?');

  if (s)
    *s='\0';

  if (strcmp(path, "/generate-ac") != 0) {
    free(path);
    soap_response(soap, 404);
    soap_end_send(soap);
    return 404;
  }

  soap_response(soap, SOAP_HTML);

  /* determine parameters */
  std::vector<std::string> fqans;
  int lifetime = -1;
  std::string orderstring;
  std::string targetstring;

  if (s) {
    ++s;

    if (!strlen(s)) {
      free(path);
      soap_response(soap, 404);
      soap_end_send(soap);
      return 500;
    }

    char *basis = s;

    do {
      char *cname;
      char *cvalue;

      if (!get_parameter(&basis, &cname, &cvalue)) {
        free(path);
        soap_response(soap, 404);
        soap_end_send(soap);
        return 500;
      }

      if (strcmp(cname, "lifetime") == 0)
        lifetime = atoi(cvalue);

      else if (strcmp(cname, "fqans") == 0) {
        char *position = strchr(cvalue, ',');

        while (position) {
          *position = '\0';
          fqans.push_back(std::string(cvalue));
          cvalue = ++position;
          position = strchr(cvalue, ',');
        }
        fqans.push_back(std::string(cvalue));
      }

      else if (strcmp(cname, "order") == 0) {
        if (orderstring.empty())
          orderstring = std::string(cvalue);
        else
          orderstring += ", " + std::string(cvalue);
      }
      else if (strcmp(cname, "targets") == 0) {
        targetstring = std::string(cvalue);
      }
      else {
        /* purposefully ignore other parameters */
        /* but put it in an otherwise positive response */
        unknown = 1;
      }
    } while (basis);
  }

  if (fqans.size()==0)
    fqans.push_back(maingroup);

  std::string command = parse_fqan(fqans);

  int res = makeACREST(soap, command, orderstring, targetstring, lifetime, unknown);

  free(path);

  return res;
}

static bool get_parameter(char **path, char **name, char **value)
{
  if (!path || !name || !value)
    return false;

  char* next = strchr(*path, '&');

  if (next)
    *next='\0';

  char *equal = strchr(*path, '=');

  if (!equal)
    return false;

  *equal='\0';

  *name = *path;
  *value = equal+1;

  if (next)
    *path = ++next;
  else
    *path = next;

  return true;
}
<|endoftext|>


<commit_before>/*  This file is part of Fabula.
    Copyright (C) 2010 Mike McQuaid <mike@mikemcquaid.com>

    Fabula 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 3 of the License, or
    (at your option) any later version.

    Fabula 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 Fabula. If not, see <http://www.gnu.org/licenses/>.
*/

#include "MainWindow.h"
#include "ui_MainWindow.h"

#include "Database.h"
#include "TableToTreeProxyModel.h"
#include "HideColumnsProxyModel.h"
#include "PreferencesDialog.h"
#include "ConversationDialog.h"
#include "CharacterDialog.h"
#include "EventDialog.h"

#include <QFileDialog>
#include <QSqlRelationalTableModel>
#include <QTableView>
#include <QFile>
#include <QDebug>
#include <QSortFilterProxyModel>
#include <QMessageBox>
#include <QKeyEvent>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    database(0),
    eventsFilterModel(0),
    conversationsTreeModel(0)
{
    ui->setupUi(this);

    QString fileName = settings.value("database").toString();

    if (fileName.isEmpty() || !QFile(fileName).exists()) {
        newFile();
    }
    else {
        openFile(fileName);
    }

    ui->statusBar->hide();

    ui->splitter->setStretchFactor(1, 1);
    QVariant treeSize = settings.value("treeSize");
    QVariant tableSize = settings.value("tableSize");
    if (treeSize.isValid() && tableSize.isValid()) {
        QList<int> splitterSizes;
        splitterSizes << treeSize.toInt() << tableSize.toInt();
        ui->splitter->setSizes(splitterSizes);
    }

    PreferencesDialog *preferences = new PreferencesDialog(this);

    connect(ui->actionNew, SIGNAL(triggered()), this, SLOT(newFile()));
    connect(ui->actionOpen, SIGNAL(triggered()), this, SLOT(openFile()));
    connect(ui->actionAdd_Event, SIGNAL(triggered()), this, SLOT(addEvent()));
    connect(ui->actionDelete_Event, SIGNAL(triggered()), this, SLOT(deleteEvent()));
    connect(ui->actionAdd_Conversation, SIGNAL(triggered()), this, SLOT(addConversation()));
    connect(ui->actionDelete_Conversation, SIGNAL(triggered()), this, SLOT(deleteConversation()));
    connect(ui->actionAdd_Character, SIGNAL(triggered()), this, SLOT(addCharacter()));
    connect(ui->actionDelete_Character, SIGNAL(triggered()), this, SLOT(deleteCharacter()));
    connect(ui->actionPreferences, SIGNAL(triggered()), preferences, SLOT(open()));

    ui->conversationsView->installEventFilter(this);
    ui->eventsView->installEventFilter(this);

    connect(ui->conversationsView, SIGNAL(clicked(QModelIndex)),
            this, SLOT(filterOnConversation(QModelIndex)));

    eventsFilterModel = new QSortFilterProxyModel(this);
    eventsFilterModel->setObjectName("eventsFilterModel");
    eventsFilterModel->setSourceModel(database->events());

    ui->eventsView->setModel(eventsFilterModel);
    ui->eventsView->hideColumn(0);
    ui->eventsView->verticalHeader()->setResizeMode(QHeaderView::ResizeToContents);

    ui->eventsView->setEditTriggers(QAbstractItemView::NoEditTriggers);
    connect(ui->eventsView, SIGNAL(activated(QModelIndex)), this, SLOT(editEvent(QModelIndex)));

    HideColumnsProxyModel *hideEventsTableColumnsModel = new HideColumnsProxyModel(this);
    hideEventsTableColumnsModel->setObjectName("hideEventsTableColumnsModel");
    QList<int> hideColumns;
    hideColumns << 0 << 1;
    hideEventsTableColumnsModel->setHideColumns(hideColumns);
    hideEventsTableColumnsModel->setSourceModel(database->events());

    conversationsTreeModel = new TableToTreeProxyModel(this);
    conversationsTreeModel->setObjectName("conversationsTreeModel");
    conversationsTreeModel->setSourceModel(hideEventsTableColumnsModel);
    ui->conversationsView->setModel(conversationsTreeModel);
    ui->conversationsView->sortByColumn(0, Qt::AscendingOrder);

    ui->conversationsView->setEditTriggers(QAbstractItemView::NoEditTriggers);
    connect(ui->conversationsView, SIGNAL(activated(QModelIndex)), this, SLOT(editTreeItem(QModelIndex)));
}

void MainWindow::newFile()
{
    QString fileName = QFileDialog::getSaveFileName(
            this, tr("New File"),
            desktopServices.storageLocation(QDesktopServices::DocumentsLocation),
            tr("Fabula Files (*.fabula)"));
    if (QFile::exists(fileName))
        QFile::remove(fileName);
    openFile(fileName);
}

void MainWindow::openFile(QString fileName)
{
    if (fileName.isEmpty()) {
        fileName = QFileDialog::getOpenFileName(
                this, tr("Open File"),
                desktopServices.storageLocation(QDesktopServices::DocumentsLocation),
                tr("Fabula Files (*.fabula)"));
    }
    if (!fileName.isEmpty()) {
        if (database) {
            delete database;
            database = 0;
        }
        database = new Database(fileName);
        settings.setValue("database", fileName);
        reloadTree();
        reloadEvents();
        setWindowTitle(QString("%1 - Fabula").arg(fileName));
        ui->centralWidget->setEnabled(true);
    }
    else {
        if (!database) {
            ui->centralWidget->setEnabled(false);
        }
    }
}

void MainWindow::filterOnConversation(const QModelIndex& index)
{
    // TODO: Get these from the database
    static const int characterRow = 2;
    static const int conversationRow = 3;

    if (!eventsFilterModel || !index.isValid())
        return;

    QString filter = index.model()->data(index).toString();
    int row = 0;
    // TODO: Do this in a less hacky fashion
    if (index.parent().isValid())
        row = conversationRow;
    else
        row = characterRow;

    eventsFilterModel->setFilterKeyColumn(row);
    eventsFilterModel->setFilterFixedString(filter);
}

void MainWindow::addEvent()
{
    QModelIndex index = ui->eventsView->currentIndex();
    if (!index.isValid())
        index = ui->eventsView->model()->index(0, 0);
    editViewItem(index, new EventDialog(database->events(), this), NewMode);
}

void MainWindow::editEvent(const QModelIndex &index)
{
    editViewItem(index, new EventDialog(database->events(), this), EditMode);
}

void MainWindow::deleteEvent()
{
    QMessageBox::StandardButton result =
            QMessageBox::question(this,
                                  "Delete confirmation",
                                  "Are you sure you wish to delete the current event?",
                                  QMessageBox::Yes | QMessageBox::No);
    if (result == QMessageBox::Yes)
        deleteViewItem(ui->eventsView->currentIndex(), database->events());
}

void MainWindow::addConversation()
{
    addOrEditTreeItem(NewMode, ConversationItem);
}

void MainWindow::editTreeItem(const QModelIndex &index)
{
    TreeItem treeItem = CharacterItem;

    // TODO: Make this less hacky
    if (index.parent().isValid())
        treeItem = ConversationItem;

    addOrEditTreeItem(EditMode, treeItem, index);
}

void MainWindow::addCharacter()
{
    addOrEditTreeItem(NewMode, CharacterItem);
}

void MainWindow::addOrEditTreeItem(DialogMode mode, TreeItem treeItem, const QModelIndex &index)
{
    const int eventsTableRow = rootModelIndex(index).row();
    int eventsTableColumn = -1;
    int itemTableNameColumn = -1;
    QSqlRelationalTableModel *tableModel = 0;
    SqlRelationalTableDialog *tableDialog = 0;

    switch (treeItem) {
        case CharacterItem:
        eventsTableColumn = 2;
        itemTableNameColumn = 1;
        tableModel = database->characters();
        tableDialog = new CharacterDialog(database->characters(), this);
        break;

    case ConversationItem:
        eventsTableColumn = 3;
        itemTableNameColumn = 3;
        tableModel = database->conversations();
        tableDialog = new ConversationDialog(database->conversations(), this);
        break;
    }

    QModelIndex eventsIndex =
            database->events()->index(eventsTableRow, eventsTableColumn);
    const QString &conversation = eventsIndex.data().toString();

    QModelIndex firstItem =
            tableModel->index(0, itemTableNameColumn);
    QModelIndexList itemIndexes =
            tableModel->match(firstItem, Qt::DisplayRole, conversation);

    Q_ASSERT(!itemIndexes.isEmpty());
    if (itemIndexes.isEmpty())
        return;

    QModelIndex itemIndex = itemIndexes.first();

    editViewItem(itemIndex, tableDialog, mode);
}

void MainWindow::deleteConversation()
{
    Q_ASSERT(false);
    QMessageBox::StandardButton result =
            QMessageBox::question(this,
                                  "Delete confirmation",
                                  "Are you sure you wish to delete the current conversation?",
                                  QMessageBox::Yes | QMessageBox::No);
    if (result == QMessageBox::Yes)
        deleteViewItem(ui->conversationsView->currentIndex(), database->conversations());
}

void MainWindow::deleteCharacter()
{
    Q_ASSERT(false);
    QMessageBox::StandardButton result =
            QMessageBox::question(this,
                                  "Delete confirmation",
                                  "Are you sure you wish to delete the current character?",
                                  QMessageBox::Yes | QMessageBox::No);
    if (result == QMessageBox::Yes)
        deleteViewItem(ui->conversationsView->currentIndex(), database->characters());
}

void MainWindow::editViewItem(const QModelIndex &index, SqlRelationalTableDialog *dialog,
                              DialogMode mode)
{
    const QModelIndex &rootIndex = rootModelIndex(index);
    Q_ASSERT(rootIndex.isValid());

    const int row = rootIndex.row();

    Q_ASSERT(dialog);
    if (!dialog)
        return;

    QSqlRelationalTableModel *model = dialog->model();
    Q_ASSERT(model);
    if (!model)
        return;

    if (mode == NewMode) {
        bool rowWasInserted = model->insertRow(row);
        Q_ASSERT(rowWasInserted);
        if (!rowWasInserted)
            return;
    }

    dialog->setRow(row);

    int result = dialog->exec();
    if (mode == NewMode && result == QDialog::Rejected) {
        bool rowWasRemoved = model->removeRow(row);
        Q_UNUSED(rowWasRemoved);
        Q_ASSERT(rowWasRemoved);
    }
    delete dialog;
}

void MainWindow::deleteViewItem(const QModelIndex &index, QSqlRelationalTableModel *model)
{
    Q_ASSERT(model);
    if (!model)
        return;

    const QModelIndex &rootIndex = rootModelIndex(index);

    bool rowWasRemoved = model->removeRow(rootIndex.row());
    Q_ASSERT(rowWasRemoved);
    if (!rowWasRemoved)
        return;
    model->submit();
}

void MainWindow::reloadTree()
{
    if (database->characters())
        database->characters()->select();
    if (database->conversations())
        database->conversations()->select();
}

void MainWindow::reloadEvents()
{
    if (database->events())
        database->events()->select();
}

QModelIndex MainWindow::rootModelIndex(const QModelIndex &index)
{
    if (!index.isValid())
        return QModelIndex();

    QModelIndex rootIndex(index);
    const QSortFilterProxyModel *proxyModel = 0;
    while ((proxyModel = qobject_cast<const QSortFilterProxyModel*>(rootIndex.model())))
        rootIndex = proxyModel->mapToSource(rootIndex);
    return rootIndex;
}

QAbstractItemModel* MainWindow::rootModel(QAbstractItemModel *model)
{
    QSortFilterProxyModel *proxyModel = 0;

    while ((proxyModel = qobject_cast<QSortFilterProxyModel*>(model)))
        model = proxyModel->sourceModel();
    return model;
}

MainWindow::~MainWindow()
{
    settings.setValue("treeSize", ui->splitter->sizes().first());
    settings.setValue("tableSize", ui->splitter->sizes().last());
    delete ui;
    delete database;
}

void MainWindow::changeEvent(QEvent *event)
{
    QMainWindow::changeEvent(event);
    switch (event->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}
bool MainWindow::eventFilter(QObject *object, QEvent *event)
{
    if (event->type() == QEvent::KeyPress) {
        QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
        // TODO: Perhaps enable backspace on OSX too?
        if (keyEvent->matches(QKeySequence::Delete)) {
            if (object == ui->eventsView) {
                ui->actionDelete_Event->trigger();
                return true;
            }
            if (object == ui->conversationsView) {
                ui->actionDelete_Conversation->trigger();
                return true;
            }
        }
    }
    return QMainWindow::eventFilter(object, event);
}
<commit_msg>Indentation fix.<commit_after>/*  This file is part of Fabula.
    Copyright (C) 2010 Mike McQuaid <mike@mikemcquaid.com>

    Fabula 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 3 of the License, or
    (at your option) any later version.

    Fabula 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 Fabula. If not, see <http://www.gnu.org/licenses/>.
*/

#include "MainWindow.h"
#include "ui_MainWindow.h"

#include "Database.h"
#include "TableToTreeProxyModel.h"
#include "HideColumnsProxyModel.h"
#include "PreferencesDialog.h"
#include "ConversationDialog.h"
#include "CharacterDialog.h"
#include "EventDialog.h"

#include <QFileDialog>
#include <QSqlRelationalTableModel>
#include <QTableView>
#include <QFile>
#include <QDebug>
#include <QSortFilterProxyModel>
#include <QMessageBox>
#include <QKeyEvent>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    database(0),
    eventsFilterModel(0),
    conversationsTreeModel(0)
{
    ui->setupUi(this);

    QString fileName = settings.value("database").toString();

    if (fileName.isEmpty() || !QFile(fileName).exists()) {
        newFile();
    }
    else {
        openFile(fileName);
    }

    ui->statusBar->hide();

    ui->splitter->setStretchFactor(1, 1);
    QVariant treeSize = settings.value("treeSize");
    QVariant tableSize = settings.value("tableSize");
    if (treeSize.isValid() && tableSize.isValid()) {
        QList<int> splitterSizes;
        splitterSizes << treeSize.toInt() << tableSize.toInt();
        ui->splitter->setSizes(splitterSizes);
    }

    PreferencesDialog *preferences = new PreferencesDialog(this);

    connect(ui->actionNew, SIGNAL(triggered()), this, SLOT(newFile()));
    connect(ui->actionOpen, SIGNAL(triggered()), this, SLOT(openFile()));
    connect(ui->actionAdd_Event, SIGNAL(triggered()), this, SLOT(addEvent()));
    connect(ui->actionDelete_Event, SIGNAL(triggered()), this, SLOT(deleteEvent()));
    connect(ui->actionAdd_Conversation, SIGNAL(triggered()), this, SLOT(addConversation()));
    connect(ui->actionDelete_Conversation, SIGNAL(triggered()), this, SLOT(deleteConversation()));
    connect(ui->actionAdd_Character, SIGNAL(triggered()), this, SLOT(addCharacter()));
    connect(ui->actionDelete_Character, SIGNAL(triggered()), this, SLOT(deleteCharacter()));
    connect(ui->actionPreferences, SIGNAL(triggered()), preferences, SLOT(open()));

    ui->conversationsView->installEventFilter(this);
    ui->eventsView->installEventFilter(this);

    connect(ui->conversationsView, SIGNAL(clicked(QModelIndex)),
            this, SLOT(filterOnConversation(QModelIndex)));

    eventsFilterModel = new QSortFilterProxyModel(this);
    eventsFilterModel->setObjectName("eventsFilterModel");
    eventsFilterModel->setSourceModel(database->events());

    ui->eventsView->setModel(eventsFilterModel);
    ui->eventsView->hideColumn(0);
    ui->eventsView->verticalHeader()->setResizeMode(QHeaderView::ResizeToContents);

    ui->eventsView->setEditTriggers(QAbstractItemView::NoEditTriggers);
    connect(ui->eventsView, SIGNAL(activated(QModelIndex)), this, SLOT(editEvent(QModelIndex)));

    HideColumnsProxyModel *hideEventsTableColumnsModel = new HideColumnsProxyModel(this);
    hideEventsTableColumnsModel->setObjectName("hideEventsTableColumnsModel");
    QList<int> hideColumns;
    hideColumns << 0 << 1;
    hideEventsTableColumnsModel->setHideColumns(hideColumns);
    hideEventsTableColumnsModel->setSourceModel(database->events());

    conversationsTreeModel = new TableToTreeProxyModel(this);
    conversationsTreeModel->setObjectName("conversationsTreeModel");
    conversationsTreeModel->setSourceModel(hideEventsTableColumnsModel);
    ui->conversationsView->setModel(conversationsTreeModel);
    ui->conversationsView->sortByColumn(0, Qt::AscendingOrder);

    ui->conversationsView->setEditTriggers(QAbstractItemView::NoEditTriggers);
    connect(ui->conversationsView, SIGNAL(activated(QModelIndex)), this, SLOT(editTreeItem(QModelIndex)));
}

void MainWindow::newFile()
{
    QString fileName = QFileDialog::getSaveFileName(
            this, tr("New File"),
            desktopServices.storageLocation(QDesktopServices::DocumentsLocation),
            tr("Fabula Files (*.fabula)"));
    if (QFile::exists(fileName))
        QFile::remove(fileName);
    openFile(fileName);
}

void MainWindow::openFile(QString fileName)
{
    if (fileName.isEmpty()) {
        fileName = QFileDialog::getOpenFileName(
                this, tr("Open File"),
                desktopServices.storageLocation(QDesktopServices::DocumentsLocation),
                tr("Fabula Files (*.fabula)"));
    }
    if (!fileName.isEmpty()) {
        if (database) {
            delete database;
            database = 0;
        }
        database = new Database(fileName);
        settings.setValue("database", fileName);
        reloadTree();
        reloadEvents();
        setWindowTitle(QString("%1 - Fabula").arg(fileName));
        ui->centralWidget->setEnabled(true);
    }
    else {
        if (!database) {
            ui->centralWidget->setEnabled(false);
        }
    }
}

void MainWindow::filterOnConversation(const QModelIndex& index)
{
    // TODO: Get these from the database
    static const int characterRow = 2;
    static const int conversationRow = 3;

    if (!eventsFilterModel || !index.isValid())
        return;

    QString filter = index.model()->data(index).toString();
    int row = 0;
    // TODO: Do this in a less hacky fashion
    if (index.parent().isValid())
        row = conversationRow;
    else
        row = characterRow;

    eventsFilterModel->setFilterKeyColumn(row);
    eventsFilterModel->setFilterFixedString(filter);
}

void MainWindow::addEvent()
{
    QModelIndex index = ui->eventsView->currentIndex();
    if (!index.isValid())
        index = ui->eventsView->model()->index(0, 0);
    editViewItem(index, new EventDialog(database->events(), this), NewMode);
}

void MainWindow::editEvent(const QModelIndex &index)
{
    editViewItem(index, new EventDialog(database->events(), this), EditMode);
}

void MainWindow::deleteEvent()
{
    QMessageBox::StandardButton result =
            QMessageBox::question(this,
                                  "Delete confirmation",
                                  "Are you sure you wish to delete the current event?",
                                  QMessageBox::Yes | QMessageBox::No);
    if (result == QMessageBox::Yes)
        deleteViewItem(ui->eventsView->currentIndex(), database->events());
}

void MainWindow::addConversation()
{
    addOrEditTreeItem(NewMode, ConversationItem);
}

void MainWindow::editTreeItem(const QModelIndex &index)
{
    TreeItem treeItem = CharacterItem;

    // TODO: Make this less hacky
    if (index.parent().isValid())
        treeItem = ConversationItem;

    addOrEditTreeItem(EditMode, treeItem, index);
}

void MainWindow::addCharacter()
{
    addOrEditTreeItem(NewMode, CharacterItem);
}

void MainWindow::addOrEditTreeItem(DialogMode mode, TreeItem treeItem, const QModelIndex &index)
{
    const int eventsTableRow = rootModelIndex(index).row();
    int eventsTableColumn = -1;
    int itemTableNameColumn = -1;
    QSqlRelationalTableModel *tableModel = 0;
    SqlRelationalTableDialog *tableDialog = 0;

    switch (treeItem) {
        case CharacterItem:
            eventsTableColumn = 2;
            itemTableNameColumn = 1;
            tableModel = database->characters();
            tableDialog = new CharacterDialog(database->characters(), this);
            break;

        case ConversationItem:
            eventsTableColumn = 3;
            itemTableNameColumn = 3;
            tableModel = database->conversations();
            tableDialog = new ConversationDialog(database->conversations(), this);
            break;
    }

    QModelIndex eventsIndex =
            database->events()->index(eventsTableRow, eventsTableColumn);
    const QString &conversation = eventsIndex.data().toString();

    QModelIndex firstItem =
            tableModel->index(0, itemTableNameColumn);
    QModelIndexList itemIndexes =
            tableModel->match(firstItem, Qt::DisplayRole, conversation);

    Q_ASSERT(!itemIndexes.isEmpty());
    if (itemIndexes.isEmpty())
        return;

    QModelIndex itemIndex = itemIndexes.first();

    editViewItem(itemIndex, tableDialog, mode);
}

void MainWindow::deleteConversation()
{
    Q_ASSERT(false);
    QMessageBox::StandardButton result =
            QMessageBox::question(this,
                                  "Delete confirmation",
                                  "Are you sure you wish to delete the current conversation?",
                                  QMessageBox::Yes | QMessageBox::No);
    if (result == QMessageBox::Yes)
        deleteViewItem(ui->conversationsView->currentIndex(), database->conversations());
}

void MainWindow::deleteCharacter()
{
    Q_ASSERT(false);
    QMessageBox::StandardButton result =
            QMessageBox::question(this,
                                  "Delete confirmation",
                                  "Are you sure you wish to delete the current character?",
                                  QMessageBox::Yes | QMessageBox::No);
    if (result == QMessageBox::Yes)
        deleteViewItem(ui->conversationsView->currentIndex(), database->characters());
}

void MainWindow::editViewItem(const QModelIndex &index, SqlRelationalTableDialog *dialog,
                              DialogMode mode)
{
    const QModelIndex &rootIndex = rootModelIndex(index);
    Q_ASSERT(rootIndex.isValid());

    const int row = rootIndex.row();

    Q_ASSERT(dialog);
    if (!dialog)
        return;

    QSqlRelationalTableModel *model = dialog->model();
    Q_ASSERT(model);
    if (!model)
        return;

    if (mode == NewMode) {
        bool rowWasInserted = model->insertRow(row);
        Q_ASSERT(rowWasInserted);
        if (!rowWasInserted)
            return;
    }

    dialog->setRow(row);

    int result = dialog->exec();
    if (mode == NewMode && result == QDialog::Rejected) {
        bool rowWasRemoved = model->removeRow(row);
        Q_UNUSED(rowWasRemoved);
        Q_ASSERT(rowWasRemoved);
    }
    delete dialog;
}

void MainWindow::deleteViewItem(const QModelIndex &index, QSqlRelationalTableModel *model)
{
    Q_ASSERT(model);
    if (!model)
        return;

    const QModelIndex &rootIndex = rootModelIndex(index);

    bool rowWasRemoved = model->removeRow(rootIndex.row());
    Q_ASSERT(rowWasRemoved);
    if (!rowWasRemoved)
        return;
    model->submit();
}

void MainWindow::reloadTree()
{
    if (database->characters())
        database->characters()->select();
    if (database->conversations())
        database->conversations()->select();
}

void MainWindow::reloadEvents()
{
    if (database->events())
        database->events()->select();
}

QModelIndex MainWindow::rootModelIndex(const QModelIndex &index)
{
    if (!index.isValid())
        return QModelIndex();

    QModelIndex rootIndex(index);
    const QSortFilterProxyModel *proxyModel = 0;
    while ((proxyModel = qobject_cast<const QSortFilterProxyModel*>(rootIndex.model())))
        rootIndex = proxyModel->mapToSource(rootIndex);
    return rootIndex;
}

QAbstractItemModel* MainWindow::rootModel(QAbstractItemModel *model)
{
    QSortFilterProxyModel *proxyModel = 0;

    while ((proxyModel = qobject_cast<QSortFilterProxyModel*>(model)))
        model = proxyModel->sourceModel();
    return model;
}

MainWindow::~MainWindow()
{
    settings.setValue("treeSize", ui->splitter->sizes().first());
    settings.setValue("tableSize", ui->splitter->sizes().last());
    delete ui;
    delete database;
}

void MainWindow::changeEvent(QEvent *event)
{
    QMainWindow::changeEvent(event);
    switch (event->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}
bool MainWindow::eventFilter(QObject *object, QEvent *event)
{
    if (event->type() == QEvent::KeyPress) {
        QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
        // TODO: Perhaps enable backspace on OSX too?
        if (keyEvent->matches(QKeySequence::Delete)) {
            if (object == ui->eventsView) {
                ui->actionDelete_Event->trigger();
                return true;
            }
            if (object == ui->conversationsView) {
                ui->actionDelete_Conversation->trigger();
                return true;
            }
        }
    }
    return QMainWindow::eventFilter(object, event);
}
<|endoftext|>


<commit_before>#include "sdl_rpc_plugin/commands/mobile/set_cloudapp_properties_request.h"

namespace sdl_rpc_plugin {
using namespace application_manager;

namespace commands {

SetCloudAppPropertiesRequest::SetCloudAppPropertiesRequest(
    const app_mngr::commands::MessageSharedPtr& message,
    app_mngr::ApplicationManager& application_manager,
    app_mngr::rpc_service::RPCService& rpc_service,
    app_mngr::HMICapabilities& hmi_capabilities,
    policy::PolicyHandlerInterface& policy_handler)
    : CommandRequestImpl(message,
                         application_manager,
                         rpc_service,
                         hmi_capabilities,
                         policy_handler) {}

SetCloudAppPropertiesRequest::~SetCloudAppPropertiesRequest() {}
void SetCloudAppPropertiesRequest::Run() {
  LOG4CXX_AUTO_TRACE(logger_);
  ApplicationSharedPtr app = application_manager_.application(connection_key());

  if (!app) {
    LOG4CXX_ERROR(logger_, "Application is not registered");
    SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED);
    return;
  }

  if ((*message_)[strings::msg_params].empty()) {
    LOG4CXX_ERROR(logger_, strings::msg_params << " is empty.");
    SendResponse(false, mobile_apis::Result::INVALID_DATA);
    return;
  }

  smart_objects::SmartObject cloud_app_properties(smart_objects::SmartType_Map);

  cloud_app_properties[strings::msg_params][strings::app_name] =
      (*message_)[strings::msg_params][strings::app_name];
  cloud_app_properties[strings::msg_params][strings::app_id] =
      (*message_)[strings::msg_params][strings::app_id];

  if ((*message_)[strings::msg_params].keyExists(strings::enabled)) {
    smart_objects::SmartObject enabled =
        (*message_)[strings::msg_params][strings::enabled];
    cloud_app_properties[strings::msg_params][strings::enabled] = enabled;
  }
  if ((*message_)[strings::msg_params].keyExists(
          strings::cloud_app_auth_token)) {
    smart_objects::SmartObject auth_token =
        (*message_)[strings::msg_params][strings::cloud_app_auth_token];
    cloud_app_properties[strings::msg_params][strings::cloud_app_auth_token] =
        auth_token;
  }
  if ((*message_)[strings::msg_params].keyExists(
          strings::cloud_transport_type)) {
    smart_objects::SmartObject transport_type =
        (*message_)[strings::msg_params][strings::cloud_transport_type];
    cloud_app_properties[strings::msg_params][strings::cloud_transport_type] =
        transport_type;
  }
  if ((*message_)[strings::msg_params].keyExists(
          strings::hybrid_app_preference)) {
    smart_objects::SmartObject hybrid_app_preference =
        (*message_)[strings::msg_params][strings::hybrid_app_preference];
    cloud_app_properties[strings::msg_params][strings::hybrid_app_preference] =
        hybrid_app_preference;
  }

  policy_handler_.OnSetCloudAppProperties(cloud_app_properties);
  SendResponse(true, mobile_apis::Result::SUCCESS);
}

void SetCloudAppPropertiesRequest::on_event(
    const app_mngr::event_engine::Event& event) {
  LOG4CXX_INFO(logger_, "SetCloudAppPropertiesRequest on_event");
}

}  // namespace commands
}  // namespace sdl_rpc_plugin<commit_msg>Removed redundant smart object<commit_after>#include "sdl_rpc_plugin/commands/mobile/set_cloudapp_properties_request.h"

namespace sdl_rpc_plugin {
using namespace application_manager;

namespace commands {

SetCloudAppPropertiesRequest::SetCloudAppPropertiesRequest(
    const app_mngr::commands::MessageSharedPtr& message,
    app_mngr::ApplicationManager& application_manager,
    app_mngr::rpc_service::RPCService& rpc_service,
    app_mngr::HMICapabilities& hmi_capabilities,
    policy::PolicyHandlerInterface& policy_handler)
    : CommandRequestImpl(message,
                         application_manager,
                         rpc_service,
                         hmi_capabilities,
                         policy_handler) {}

SetCloudAppPropertiesRequest::~SetCloudAppPropertiesRequest() {}

void SetCloudAppPropertiesRequest::Run() {
  LOG4CXX_AUTO_TRACE(logger_);
  ApplicationSharedPtr app = application_manager_.application(connection_key());

  if (!app) {
    LOG4CXX_ERROR(logger_, "Application is not registered");
    SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED);
    return;
  }

  if ((*message_)[strings::msg_params].empty()) {
    LOG4CXX_ERROR(logger_, strings::msg_params << " is empty.");
    SendResponse(false, mobile_apis::Result::INVALID_DATA);
    return;
  }

  policy_handler_.OnSetCloudAppProperties(*message_);
  SendResponse(true, mobile_apis::Result::SUCCESS);
}

void SetCloudAppPropertiesRequest::on_event(
    const app_mngr::event_engine::Event& event) {
  LOG4CXX_INFO(logger_, "SetCloudAppPropertiesRequest on_event");
}

}  // namespace commands
}  // namespace sdl_rpc_plugin<|endoftext|>


<commit_before>/**
 * This file is part of Slideshow.
 * Copyright (C) 2008-2010 David Sveningsson <ext@sidvind.com>
 *
 * Slideshow is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * Slideshow 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with Slideshow.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifdef HAVE_CONFIG_H
#	include "config.h"
#endif

#include "Log.h"
#include "VideoState.h"
#include "SwitchState.h"
#include <cstdlib>
#include <cstring>
#include <cerrno>
#include <cassert>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/wait.h>
#include <portable/asprintf.h>

static char read_buffer[1024];
static int child_pid = -1;
static int child_stdin = -1;
static int child_stdout = -1;

static const char* read2(int fd){
	while ( read(fd, read_buffer, 1024) > 0 ){
		if ( strncmp(read_buffer, "ANS_", 4) == 0 ){
			return read_buffer;
		}

		Log::message(Log_Verbose, "mplayer: %s", read_buffer);
	}

	switch ( errno ){
		case EWOULDBLOCK:
			break;
		default:
			Log::message(Log_Warning, "mplayer: read failed with code %d\n", errno);
	}

	return NULL;
}

void VideoState::command(const char* fmt, ...){
	assert(child_pid > 0);

	va_list ap;
	va_start(ap, fmt);
	char* tmp = vasprintf2(fmt, ap);
	write(child_stdin, tmp, strlen(tmp));
	free(tmp);
	va_end(ap);
}

VideoState::VideoState(State* state, const char* filename)
	: State(state)
	, _filename(strdup(filename)){

	if ( child_pid <= 0 ){
		Log::message(Log_Verbose, "no mplayer: process, cannot play video\n");
		return;
	}

	command("loadfile %s\n", filename);
}

VideoState::~VideoState(){
	free(_filename);
	_filename = NULL;
}

State* VideoState::action(bool &flip){
	if ( !child_pid <= 0 ){
		return new SwitchState(this);
	}

	command("get_property filename\n");

	while ( true ){
		const char* ans = read2(child_stdout);

		if ( !ans ){
			continue;
		}

		if ( strcmp(ans, "ANS_ERROR=PROPERTY_UNAVAILABLE\n") == 0){
			return new SwitchState(this);
		}

		return this;
	}
}

int VideoState::init(){
	/* Fork and get child std{in,out} */
	/* http://lists.mplayerhq.hu/pipermail/mplayer-dev-eng/2007-August/053602.html */

	int pipefds1[2];
	int pipefds2[2];

	pipe2(pipefds1, O_NONBLOCK);
	pipe2(pipefds2, O_NONBLOCK);

	child_pid = fork();

	close(pipefds1[!!child_pid]);
	close(pipefds2[!child_pid]);

	if (!child_pid) { /* in child process */
		dup2(pipefds1[1], STDOUT_FILENO);
		dup2(pipefds2[0], STDIN_FILENO);
		return execlp("mplayer", "slideshow-mplayer", "-slave", "-idle", "-quiet", "-msglevel", "all=-1:global=4", "-fs", NULL);
	} else { /* in parent process */
		child_stdin  = pipefds2[1];
		child_stdout = pipefds1[0];
		return 0;
	}
}

int VideoState::cleanup(){
	if ( child_pid > 0 ){
		command("quit\n");
	}
	return 0;
}

void VideoState::poll(){
	if ( child_pid < 0 ){
		return;
	}

	int sigstate = kill(child_pid, 0);
	if ( sigstate != 0 ){ /* child process terminated */
		Log::message(Log_Fatal, "mplayer process has gone away (for reasons unknown)");
		child_pid = -1;
	}

	int status;
	if ( waitpid(child_pid, &status, WNOHANG) != 0 ){
		if ( WIFEXITED(status) ){
			Log::message(Log_Fatal, "mplayer process has gone away (exited with code %d)\n", WEXITSTATUS(status));
		} else {
			Log::message(Log_Fatal, "mplayer process has gone away (terminated with signal %d)\n", WTERMSIG(status));
		}
		child_pid = -1;
	}

	read2(child_stdout);
}
<commit_msg>proper path to video (filename is slidepath, the symlink to video is *.slide/src/video<commit_after>/**
 * This file is part of Slideshow.
 * Copyright (C) 2008-2010 David Sveningsson <ext@sidvind.com>
 *
 * Slideshow is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * Slideshow 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with Slideshow.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifdef HAVE_CONFIG_H
#	include "config.h"
#endif

#include "Log.h"
#include "VideoState.h"
#include "SwitchState.h"
#include <cstdlib>
#include <cstring>
#include <cerrno>
#include <cassert>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/wait.h>
#include <portable/asprintf.h>

static char read_buffer[1024];
static int child_pid = -1;
static int child_stdin = -1;
static int child_stdout = -1;

static const char* read2(int fd){
	while ( read(fd, read_buffer, 1024) > 0 ){
		if ( strncmp(read_buffer, "ANS_", 4) == 0 ){
			return read_buffer;
		}

		Log::message(Log_Verbose, "mplayer: %s", read_buffer);
	}

	switch ( errno ){
		case EWOULDBLOCK:
			break;
		default:
			Log::message(Log_Warning, "mplayer: read failed with code %d\n", errno);
	}

	return NULL;
}

void VideoState::command(const char* fmt, ...){
	assert(child_pid > 0);

	va_list ap;
	va_start(ap, fmt);
	char* tmp = vasprintf2(fmt, ap);
	write(child_stdin, tmp, strlen(tmp));
	free(tmp);
	va_end(ap);
}

VideoState::VideoState(State* state, const char* filename)
	: State(state)
	, _filename(strdup(filename)){

	if ( child_pid <= 0 ){
		Log::message(Log_Verbose, "no mplayer: process, cannot play video\n");
		return;
	}

	command("loadfile %s/src/video\n", filename);
}

VideoState::~VideoState(){
	free(_filename);
	_filename = NULL;
}

State* VideoState::action(bool &flip){
	if ( !child_pid <= 0 ){
		return new SwitchState(this);
	}

	command("get_property filename\n");

	while ( true ){
		const char* ans = read2(child_stdout);

		if ( !ans ){
			continue;
		}

		if ( strcmp(ans, "ANS_ERROR=PROPERTY_UNAVAILABLE\n") == 0){
			return new SwitchState(this);
		}

		return this;
	}
}

int VideoState::init(){
	/* Fork and get child std{in,out} */
	/* http://lists.mplayerhq.hu/pipermail/mplayer-dev-eng/2007-August/053602.html */

	int pipefds1[2];
	int pipefds2[2];

	pipe2(pipefds1, O_NONBLOCK);
	pipe2(pipefds2, O_NONBLOCK);

	child_pid = fork();

	close(pipefds1[!!child_pid]);
	close(pipefds2[!child_pid]);

	if (!child_pid) { /* in child process */
		dup2(pipefds1[1], STDOUT_FILENO);
		dup2(pipefds2[0], STDIN_FILENO);
		return execlp("mplayer", "slideshow-mplayer", "-slave", "-idle", "-quiet", "-msglevel", "all=-1:global=4", "-fs", NULL);
	} else { /* in parent process */
		child_stdin  = pipefds2[1];
		child_stdout = pipefds1[0];
		return 0;
	}
}

int VideoState::cleanup(){
	if ( child_pid > 0 ){
		command("quit\n");
	}
	return 0;
}

void VideoState::poll(){
	if ( child_pid < 0 ){
		return;
	}

	int sigstate = kill(child_pid, 0);
	if ( sigstate != 0 ){ /* child process terminated */
		Log::message(Log_Fatal, "mplayer process has gone away (for reasons unknown)");
		child_pid = -1;
	}

	int status;
	if ( waitpid(child_pid, &status, WNOHANG) != 0 ){
		if ( WIFEXITED(status) ){
			Log::message(Log_Fatal, "mplayer process has gone away (exited with code %d)\n", WEXITSTATUS(status));
		} else {
			Log::message(Log_Fatal, "mplayer process has gone away (terminated with signal %d)\n", WTERMSIG(status));
		}
		child_pid = -1;
	}

	read2(child_stdout);
}
<|endoftext|>


<commit_before>/* All or part of this file was contributed by Intel under license:
 *   Copyright (C) 2017-2018 Intel Corporation
 *   SPDX-License-Identifier: MIT
 */

#include "tensors/cpu/backend.h"
#include "tensors/tensor.h"
#include "tensors/tensor_allocator.h"

#if MKL_FOUND
#include <mkl.h>
#else
#if BLAS_FOUND
#include <cblas.h>
#endif
#endif

#include "sharp/int_gemm.h"

namespace marian {

namespace cpu {

#if BLAS_FOUND
inline void sgemm(bool transA,
                  bool transB,
                  int rows_a,
                  int rows_b,
                  int width,
                  float alpha,
                  float* a,
                  int lda,
                  float* b,
                  int ldb,
                  float beta,
                  float* c,
                  int ldc) {
  cblas_sgemm(CblasRowMajor,
              transA ? CblasTrans : CblasNoTrans,
              transB ? CblasTrans : CblasNoTrans,
              rows_a,
              rows_b,
              width,
              alpha,
              a,
              lda,
              b,
              ldb,
              beta,
              c,
              ldc);
}
#endif

void Prod(marian::Tensor C,
          const marian::Tensor& A,
          const marian::Tensor& B,
          bool transA,
          bool transB,
          float beta,
          float scalar) {
#if BLAS_FOUND
  float alpha = scalar;

  int m = A->shape().elements() / A->shape()[-1];
  int k = A->shape().back();
  if(transA)
    std::swap(m, k);

  int l = B->shape().elements() / B->shape()[-1];
  int n = B->shape()[-1];
  if(transB)
    std::swap(l, n);

  int lda = A->shape()[-1];
  int ldb = B->shape()[-1];
  int ldc = B->shape()[-1];

  if(transB)
    ldc = B->shape().elements() / B->shape()[-1];

  sgemm(transA,
        transB,
        m,
        n,
        k,
        alpha,
        A->data(),
        lda,
        B->data(),
        ldb,
        beta,
        C->data(),
        ldc);
#else
  C; A; B; transA; transB; beta; scalar;
  ABORT("You need to compile with MKL in order to use the CPU version");
#endif
}

void ProdBatched(marian::Tensor C,
                 Ptr<Allocator> /*allocator*/,
                 const marian::Tensor A,
                 const marian::Tensor B,
                 bool transA,
                 bool transB,
                 float beta,
                 float scalar) {
#if BLAS_FOUND
  float alpha = scalar;

  size_t batchA = A->shape().elements() / (A->shape()[-1] * A->shape()[-2]);
  size_t batchB = B->shape().elements() / (B->shape()[-1] * B->shape()[-2]);

  size_t m = A->shape()[-2];
  size_t k = A->shape()[-1];
  if(transA)
    std::swap(m, k);

  size_t l = B->shape()[-2];
  size_t n = B->shape()[-1];
  if(transB)
    std::swap(l, n);

  size_t lda = A->shape()[-1];
  size_t ldb = B->shape()[-1];
  size_t ldc = B->shape()[-1];

  if(transB)
    ldc = B->shape()[-2];

  auto strideB = batchB == 1 ? 0 : n * k;
  auto strideA = batchA == 1 ? 0 : m * k;
  auto strideC = n * m;

  auto batchC = std::max(batchA, batchB);
  for(size_t i = 0; i < batchC; ++i) {
    sgemm(transA,
          transB,
          (int)m,
          (int)n,
          (int)k,
          alpha,
          A->data() + (i % batchA) * strideA,
          (int)lda,
          B->data() + (i % batchB) * strideB,
          (int)ldb,
          beta,
          C->data() + i * strideC,
          (int)ldc);
  }
#else
  C; A; B; transA; transB; beta; scalar;
  ABORT("You need to compile with MKL in order to use the CPU version");
#endif
}

void ProdWithBias(marian::Tensor C,
                  const marian::Tensor& A,
                  const marian::Tensor& B,
                  const marian::Tensor& bias,
                  bool transA,
                  bool transB,
                  float beta,
                  float scalar) {
  cpu::Prod(C, A, B, transA, transB, beta, scalar);
  cpu::int16::AddBias(C, bias);
}

void CSRProd(marian::Tensor C,
             Ptr<Allocator> /*allocator*/,
             const marian::Tensor& A_values,
             const marian::Tensor& A_indices,
             const marian::Tensor& A_offsets,
             const marian::Tensor& B,
             bool transA,
             bool swapOperands,
             float beta) {
  C, A_values, A_indices, A_offsets, B, transA, swapOperands, beta;
  ABORT("CSRProd is not yet implemented for CPU");
}

}  // namespace cpu
}  // namespace marian
<commit_msg>implemented cpu::CSRProd() for decoding<commit_after>/* All or part of this file was contributed by Intel under license:
 *   Copyright (C) 2017-2018 Intel Corporation
 *   SPDX-License-Identifier: MIT
 */

#include "tensors/cpu/backend.h"
#include "tensors/tensor.h"
#include "tensors/tensor_allocator.h"

#if MKL_FOUND
#include <mkl.h>
#else
#if BLAS_FOUND
#include <cblas.h>
#endif
#endif

#include "sharp/int_gemm.h"

namespace marian {

namespace cpu {

#if BLAS_FOUND
inline void sgemm(bool transA,
                  bool transB,
                  int rows_a,
                  int rows_b,
                  int width,
                  float alpha,
                  float* a,
                  int lda,
                  float* b,
                  int ldb,
                  float beta,
                  float* c,
                  int ldc) {
  cblas_sgemm(CblasRowMajor,
              transA ? CblasTrans : CblasNoTrans,
              transB ? CblasTrans : CblasNoTrans,
              rows_a,
              rows_b,
              width,
              alpha,
              a,
              lda,
              b,
              ldb,
              beta,
              c,
              ldc);
}
#endif

void Prod(marian::Tensor C,
          const marian::Tensor& A,
          const marian::Tensor& B,
          bool transA,
          bool transB,
          float beta,
          float scalar) {
#if BLAS_FOUND
  float alpha = scalar;

  int m = A->shape().elements() / A->shape()[-1];
  int k = A->shape().back();
  if(transA)
    std::swap(m, k);

  int l = B->shape().elements() / B->shape()[-1];
  int n = B->shape()[-1];
  if(transB)
    std::swap(l, n);

  int lda = A->shape()[-1];
  int ldb = B->shape()[-1];
  int ldc = B->shape()[-1];

  if(transB)
    ldc = B->shape().elements() / B->shape()[-1];

  sgemm(transA,
        transB,
        m,
        n,
        k,
        alpha,
        A->data(),
        lda,
        B->data(),
        ldb,
        beta,
        C->data(),
        ldc);
#else
  C; A; B; transA; transB; beta; scalar;
  ABORT("You need to compile with MKL in order to use the CPU version");
#endif
}

void ProdBatched(marian::Tensor C,
                 Ptr<Allocator> /*allocator*/,
                 const marian::Tensor A,
                 const marian::Tensor B,
                 bool transA,
                 bool transB,
                 float beta,
                 float scalar) {
#if BLAS_FOUND
  float alpha = scalar;

  size_t batchA = A->shape().elements() / (A->shape()[-1] * A->shape()[-2]);
  size_t batchB = B->shape().elements() / (B->shape()[-1] * B->shape()[-2]);

  size_t m = A->shape()[-2];
  size_t k = A->shape()[-1];
  if(transA)
    std::swap(m, k);

  size_t l = B->shape()[-2];
  size_t n = B->shape()[-1];
  if(transB)
    std::swap(l, n);

  size_t lda = A->shape()[-1];
  size_t ldb = B->shape()[-1];
  size_t ldc = B->shape()[-1];

  if(transB)
    ldc = B->shape()[-2];

  auto strideB = batchB == 1 ? 0 : n * k;
  auto strideA = batchA == 1 ? 0 : m * k;
  auto strideC = n * m;

  auto batchC = std::max(batchA, batchB);
  for(size_t i = 0; i < batchC; ++i) {
    sgemm(transA,
          transB,
          (int)m,
          (int)n,
          (int)k,
          alpha,
          A->data() + (i % batchA) * strideA,
          (int)lda,
          B->data() + (i % batchB) * strideB,
          (int)ldb,
          beta,
          C->data() + i * strideC,
          (int)ldc);
  }
#else
  C; A; B; transA; transB; beta; scalar;
  ABORT("You need to compile with MKL in order to use the CPU version");
#endif
}

void ProdWithBias(marian::Tensor C,
                  const marian::Tensor& A,
                  const marian::Tensor& B,
                  const marian::Tensor& bias,
                  bool transA,
                  bool transB,
                  float beta,
                  float scalar) {
  cpu::Prod(C, A, B, transA, transB, beta, scalar);
  cpu::int16::AddBias(C, bias);
}

void CSRProd(marian::Tensor C,
             Ptr<Allocator> /*allocator*/,
             const marian::Tensor& S_values,
             const marian::Tensor& S_indices,
             const marian::Tensor& S_offsets,
             const marian::Tensor& D,
             bool transS,
             bool swapOperands,
             float beta) {
  C, S_values, S_indices, S_offsets, D;

  // Note: The CPU implementation currently only implements what's needed for decoding.

  // interpret tensor dimensions as matrix dimensions
  const auto& shapeC = C->shape();
  const auto& shapeD = D->shape();
  // If swapOperands, S and D are swapped (C = D x S instead of C = S x D).
  // In that case, in the next 6 lines, please read all dimensions as if they were reversed in order.
  auto rowsC = shapeC[-(int)swapOperands];
  auto colsC = shapeC.elements() / rowsC;
  auto rowsD = shapeD[-(int)swapOperands];
  auto colsD = shapeD.elements() / rowsD;
  auto rowsS = transS ? rowsD : rowsC;
  auto colsS = transS ? rowsC : rowsD;
  ABORT_IF(colsD != colsC, "Inconsistent outer dimensions in CSR product");
  if (swapOperands) { // make rowsX actual row dimensions again, likewise colsX
    std::swap(rowsC, colsC);
    std::swap(rowsD, colsD);
    std::swap(rowsS, colsS);
  }
  // sparse arrays
  auto numValues  = S_values->shape().elements();
  auto numOffsets = S_offsets->shape().elements() - 1; // -1 since last value is length
  ABORT_IF(numOffsets != rowsS, "Unexpected number of rows in CSR argument");
  ABORT_IF(S_values->shape() != S_indices->shape(), "CSR values and indices must have the same size");
  if (!transS && !swapOperands) {
    // C = S * D, where D = CSR matrix
    const auto* offsets = S_offsets->data<IndexType>();
    const auto* indices = S_indices->data<IndexType>();
    const auto* values  = S_values->data<float>();
    const auto* dataD   = D->data<float>();
    auto*       dataC   = C->data<float>();
    ABORT_IF(beta != 0 && beta != 1, "cpu::CSRProd only supports beta = 0 or 1");
    for (size_t i = 0; i < rowsC; i++) {
      auto add = (beta == 1); // first element: overwrite or add according to beta; subsequent elements: add
      for (size_t kk = offsets[i]; kk < offsets[i + 1]; kk++) {
        auto k = indices[kk];    // fetch the non-zero row
        auto valS = values[kk]; // and the value from that row
        // This code is written with the hope for good vectorization, and the hope
        // that adding to memory will be done efficiently by the caching system.
        if (valS == 1)
          if (!add)
            for (size_t j = 0; j < colsC; j++)
              dataC[i * colsC/*==colsD*/ + j] = dataD[k * colsC/*==colsD*/ + j]; // this is a memcpy()
          else
            for (size_t j = 0; j < colsC; j++)
              dataC[i * colsC/*==colsD*/ + j] += dataD[k * colsC/*==colsD*/ + j]; // this is a contiguous-vector addition
        else
          if (!add)
            for (size_t j = 0; j < colsC; j++)
              dataC[i * colsC/*==colsD*/ + j] = valS * dataD[k * colsC/*==colsD*/ + j];
          else
            for (size_t j = 0; j < colsC; j++)
              dataC[i * colsC/*==colsD*/ + j] += valS * dataD[k * colsC/*==colsD*/ + j]; // notice the +=
        add = true; // next iteration will add to existing result
      }
    }
  }
  else
    ABORT("CSRProd for transS={}, swapOperands={} is not yet implemented for CPU", transS, swapOperands);
}

}  // namespace cpu
}  // namespace marian
<|endoftext|>


<commit_before>//
// Created by Miguel Rentes on 30/01/2017.
//

#include "STL.h"

void printKMax(int arr[], int n, int k) {
    deque<int> mydeque;
    int greatest = 0, value = 0, index = 0, iteration = 0;
    /*
     * pushing all the greatest values on each k-elements to the front of the deque
     */
    for (int i = 0; i < n; i++) {
        if (index < k) {
            value = arr[i];
            if (value > greatest)
                greatest = value;
            if (index == k - 1) {
                mydeque.push_front(greatest);
                greatest = 0;
                index = 0;
                iteration++;
                i = iteration-1;
            } else {
                index++;
            }
        }
    }
    /*
     * pop-ing the greatest values from the back of the deque
     */
    while(mydeque.size() > 0) {
        printf("%d ", mydeque.back());
        mydeque.pop_back();
    }
    printf("\n");
}

int main(void) {
    int t;
    cin >> t;
    while (t > 0) {
        int n, k;
        cin >> n >> k;
        int i;
        int arr[n];
        for (i = 0; i < n; i++)
            cin >> arr[i];
        printKMax(arr, n, k);
        t--;
    }
    return EXIT_SUCCESS;
}<commit_msg>Starts solution for the Deque-STL challenge.<commit_after>//
// Created by Miguel Rentes on 30/01/2017.
//

#include "STL.h"

void printKMax(int arr[], int n, int k) {
    deque<int> mydeque;
    int greatest = 0;
    int value = 0;
    int index = 0;
    int iteration = 0;
    /*
     * pushing all the greatest values on each k-elements to the front of the deque
     */
    for (int i = 0; i < n; i++) {
        if (index < k) {
            value = arr[i];
            if (value > greatest)
                greatest = value;
            if (index == k - 1) {
                mydeque.push_front(greatest);
                greatest = 0;
                index = 0;
                iteration++;
                i = iteration-1;
            } else {
                index++;
            }
        }
    }
    /*
     * pop-ing the greatest values from the back of the deque
     */
    while(mydeque.size() > 0) {
        printf("%d ", mydeque.back());
        mydeque.pop_back();
    }
    printf("\n");
}

int main(void) {
    int t;
    cin >> t;
    while (t > 0) {
        int n, k;
        cin >> n >> k;
        int i;
        int arr[n];
        for (i = 0; i < n; i++)
            cin >> arr[i];
        printKMax(arr, n, k);
        t--;
    }
    return EXIT_SUCCESS;
}<|endoftext|>